Next printf comes before my scanf takes input - c

I am creating a calculator file in C with a while loop and a switch statement. The first time through the while loop, everything works fine, but when it goes through the second time, the my printf gets called before I have the opportunity to enter the data into the preceding scanf.
I have tried using '\n' before the text in the printf and I have also tried using fflush(stdout) before and after the scanf call.
Current output:
Welcome to the Calculator
Operation choices: Addition(A)
Subtraction(S)
Multiplication(M)
Division(D).
Enter choice: A
Enter both numbers in required sequence: 50 50
// the output of the calculator does <>= 100 // Equal to 100.
Welcome to the Calculator
Operation choices: Addition(A)
Subtraction(S)
Multiplication(M)
Division(D).
Enter choice: Enter both numbers in required sequence:
What I want:
Welcome to the Calculator
Operation choices: Addition(A)
Subtraction(S)
Multiplication(M)
Division(D).
Enter choice: A
Enter both numbers in required sequence: 50 50
// the output of the calculator does <>= 100 // Equal to 100.
Welcome to the Calculator
Operation choices: Addition(A)
Subtraction(S)
Multiplication(M)
Division(D).
Enter choice: // then I can enter a new choice for the switch //
The code I've tried:
while(input != 'q'){
printf("Welcome to the Calculator\nOperation choices:\tAddition(A)\n\t\t\tSubtraction(S)\n\t\t\tMultiplication(M)\n\t\t\tDivision(D)\nEnter choice: ");
fflush(stdout);
scanf("%c", &input);
fflush(stdout);
printf("\nEnter both numbers in required sequence: ");
scanf("%f %f", &num1, &num2);
switch(input){
case 'A':
result = num1 + num2;
break;
case 'S':
result = num1 - num2;
break;
case 'M':
result = num1 * num2;
break;
case 'D':
result = num1 / num2;
break;
default:
printf("Please choose a valid operation.");
break;
}
if(result > 100){
printf("Greater than 100.\n");
}
else if(result < 100) {
printf("Less than 100.\n");
}
else{
printf("Equal to 100.\n");
}
}
printf("Quit the menu.\n");
return(0);
}

The sequence of events in you program is correct, what happens is that scanf() reads a lingering '\n' new line character that is left in the stdin buffer from a previous input. The '\n' is consumed by scanf() and the program continues the execution.
You will need to clear the buffer before scanf() is executed.
Option 1 - Clear the buffer at the bottom of the while cycle:
//...
int c;
//...
else{
printf("Equal to 100.\n");
}
while((c = fgetc(stdin)) != '\n' && c != EOF){}
//...
Option 2 (simpler) - Use a space before %c specifier:
scanf(" %c", &input);
^

Try this : scanf(" %c", &input); (add space before %c)
scanf will likely take \n in buffer as input and placed in you character input.

Related

getchar() not waiting for input and jumping directly to next line

getchar() not waiting for input and jumping directly to next line. There is some mismatch between scanf and getchar I think but not able to make out what is it exactly.
#include<stdio.h>
#include<ctype.h>
int main()
{
char ch;
int n1,n2;
printf("Enter the operation of your choice\n");
printf("a. add\ts. subtact\nm. multiply\td. divide\nq. quit\n");
while((ch=getchar())!='q')
{
printf("\nEnter 1st number:\n");
if(scanf("%d",&n1)!=1)
{
printf("Please enter an integer value.\n");
continue;
}
printf("Enter 2nd number:\n");
if(scanf("%d",&n2)!=1)
{
printf("Please enter an integer value.\n");
continue;
}
switch(ch)
{
case 'a':
{ printf(" %d + %d = %d\n",n1,n2,n1+n2);
break;
}
case 's':
{
printf(" %d - %d = %d\n",n1,n2,n1-n2);
break;
}
case 'm':
{
printf(" %d * %d = %d\n",n1,n2,n1*n2);
break;
}
case 'd':
{
if(n2!=0)
{
printf(" %d / %d = %f\n",n1,n2,(float)n1/n2);
break;
}
else
{
printf("Enter a non-zero number for n2\n");
continue;
}
break;
}
}
printf("Enter the operation of your choice\n");
printf("a. add\ts. subtact\nm. multiply\td. divide\nq. quit\n");
}
printf("Bye.");
}
OUTPUT:
Enter the operation of your choice
a. add s. subtact
m. multiply d. divide
q. quit
a
Enter 1st number:
50
Enter 2nd number:
25
50 + 25 = 75
Enter the operation of your choice
a. add s. subtact
m. multiply d. divide
q. quit
Enter 1st number:
your getchar reads the newline and other spaces you enter when you give the value read by the scanf, you need to bypass these spaces
just replace
while((ch=getchar())!='q')
by
while ((scanf(" %c", &ch) == 1) && (ch != 'q'))
notice the space before '%', this is thank to it the spaces including newline are bypassed

y/n loop at the end of a function

good evening,
Here is my code. I am making a little calculator but I'm battling at the end to make the function repeat with a y/n loop. I have looked at others but can't seem to get the right answer.
Thanks.
#include <stdio.h>
int main()
{
int n, num1, num2, result;
char answer;
{
printf("\nWhat operation do you want to perform?\n");
printf("Press 1 for addition.\n");
printf("Press 2 for subtraction.\n");
printf("Press 3 for multiplication.\n");
printf("Press 4 for division.\n");
scanf("%d", &n);
printf("Please enter a number.\n");
scanf("%d", &num1);
printf("Please enter the second number.\n");
scanf("%d", &num2);
switch(n)
{
case 1: result = num1 + num2;
printf("The addition of the two numbers is %d\n", result );
break;
case 2: result = num1 - num2;
printf("The subtraction of the two numbers is %d\n", result );
break;
case 3: result = num1 * num2;
printf("The multiplication of the two numbers is %d\n", result );
break;
case 4: result = num1 / num2;
printf("The division of the two numbers is %d\n", result );
break;
default: printf("Wrong input!!!");
}
printf("\nDo you want to continue, y/n?\n");
scanf("%c", &answer);
while(answer == 'y');
}
return 0;
}
You have this code
char answer;
{
printf("\nWhat operation do you want to perform?\n");
//...
//... more code
//...
printf("\nDo you want to continue, y/n?\n");
scanf("%c", &answer);
while(answer == 'y');
}
Try to change it to:
char answer;
do {
printf("\nWhat operation do you want to perform?\n");
//...
//... more code
//...
printf("\nDo you want to continue, y/n?\n");
scanf("%c", &answer);
} while(answer == 'y');
So the basic form is:
do {
// code to repeat
} while (Boolean-expression);
BTW - You should always check the value returned by scanf
Example:
if (scanf("%c", &answer) != 1)
{
// Add error handling
}
Also notice that you often want a space before %c to remove any white space (including newlines) in the input stream. Like
if (scanf(" %c", &answer) != 1)
{
// Add error handling
}

How to make this program ask for input again if invalid input is entered (in C programming)? [duplicate]

This question already has answers here:
Why is scanf() causing infinite loop in this code?
(16 answers)
Closed 5 years ago.
There are two different spots where the check happens.
That is, where you enter a, s, m, d, or q and when you enter the first and second number.
At any of the checks, if the check is false, it should ask you to re-enter your input.
I'm guessing this can be done by putting a scanf statement for the numbers part inside a while loop check, but when I enter an invalid value (non-number) the loop runs infinitely.
So I must be doing something wrong. I have made the a, s, m, d, and q part work for the most part.
But the second part never seems to work. For this, I left my failed attempts at the while loops out, and instead in //comments.
Any help would be greatly appreciated!
Here is my code so far:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
float num1,num2,answer;
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
while ((ch = getchar())!='q')
{
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
ch=tolower(ch);
if (ch=='\n')
continue;
else
{
switch(ch)
{
case 'a':
//The code below is what I have tried to make work.
//This code would also be copy pasted to the other cases,
//of course with the correct operations respectively being used.
//
//printf("Enter first number: ")
//while(scanf("%f",&num1)==0)
//{
// printf("Invalid input. Please enter a number.");
// scanf("%f",&num1);
//}
//printf("Enter second number: ")
//while(scanf("%f",&num2)==0)
//{
// printf("Invalid input. Please enter a number.");
// scanf("%f",&num2);
//}
//answer = num1 + num2;
//printf("%f + %f = %f\n",num1,num2,answer);
//break;
//
//I have also tried to make this work using do-while loops
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 + num2;
printf("%f + %f = %f\n",num1,num2,answer);
break;
case 's':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 - num2;
printf("%f - %f = %f\n",num1,num2,answer);
break;
case 'm':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 * num2;
printf("%f * %f = %f\n",num1,num2,answer);
break;
case 'd':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 / num2;
printf("%f / %f = %f\n",num1,num2,answer);
break;
default:
printf("That is not a valid operation.\n");
break;
}
}
}
return 0;
}
Again, thanks for any help!
Ya'll would be a life saver!
Cheers!
-Will S.
EDIT: I got my code to work! Here is the final code...
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
float num1,num2,answer;
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
while ((ch = getchar())!='q')
{
ch=tolower(ch);
//Ignore whitespace
if (ch=='\n')
continue;
else
{
switch(ch)
{
//Addition part
case 'a':
//First number
printf("Enter first number: ");
//Check to see if input is a number
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Second number
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Do math for respective operation
answer = num1 + num2;
//Print out result
printf("%.3f + %.3f = %.3f\n", num1,num2,answer);
break;
//Subtraction part
case 's':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
answer = num1 - num2;
printf("%.3f - %.3f = %.3f\n", num1,num2,answer);
break;
//Multiplication part
case 'm':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
answer = num1 * num2;
printf("%.3f * %.3f = %.3f\n", num1,num2,answer);
break;
//Division part
case 'd':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Check for if number is a zero
while (num2==0)
{
printf("Please enter a non-zero number, such as 2.5, -1.78E8, or 3: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
}
answer = num1 / num2;
printf("%.3f / %.3f = %.3f\n", num1,num2,answer);
break;
//For if a non-valid operation is entered
default:
printf("That is not a valid operation.\n");
break;
}
}
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
}
printf("Bye.\n");
return 0;
}
Looking back at it, I probably could do without the if/else statement.
There are multiple problems with your code. First of all in this loop
You are taking input two times on failure
while(scanf("%f",&num1)==0) //Taking Input Here Once
{
printf("Invalid input. Please enter a number.");
scanf("%f",&num1); //Again Taking input.
}
Instead what you wanted was to check the return value of the scanf() and if it was 0 you would execute the loop again, so this would be the way to do that:
int l = 0;
while(l==0){ //Checking l, if it is zero or not, if zero running loop again.
printf("Invalid input. Please enter a number.");
l = scanf("%f",&num1); //Storing Return Value of scanf in l
}
When the program will encounter any line with scanf("%f" , &num1) or scanf("%f" , &num2), it will skip all the white spaces and wait for next input. In the case where the input does not match the format specification, then the input isn't consumed and remains in the input buffer.
int l = 0;
while(l==0){ //Checking l
printf("Invalid input. Please enter a number.");
l = scanf("%f",&num1); //scanf will look at the buffer if the input
//does not match, it will not be consumed
//and will remain in buffer.
}
In other words, the character that doesn't match is never read. So when you type e.g. an a character, your code will loop indefinitely as scanf continues to fail on the same character.
When the program executes its last scanf("%f",&num2) call then because of the enter there is a newline \n character present in buffer and so due to ch = getchar(), new line \n gets stored in ch and the following if condition satisfies and the loop execute again.
if(ch =='\n')
continue;
while(scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number.");
scanf("%f",&num1);
}
This loops scans two numbers per iteration. This is not what you want. Lose the second scanf.
You should also check for EOF and errors.
int result;
while((result = scanf("%f",&num1))==0)
{
printf("Invalid input. Please enter a number.");
}
if (result == EOF) .... report an error and exit ...

How do I get my code from going into an infinte loop?

I am rewriting the Guessing Game code from 'C Programming for Absoulute Beginners' to verify that the user has entered in a digit, using the isdigit() function.
The rest of the code works, in terms of error checking; but the moment that the user enters in a non-digit, the code goes into an infinite loop.
#include <stdio.h>
#include <stdlib.h>
#define NO 2
#define YES 1
main()
{
int guessGame;
guessGame = 0;
int iRandomNum = 0;
int iResponse = 0;
printf("\n\nWould you like to play \"The Guessing Game\"?\n\n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
do{
if(guessGame == YES){
iRandomNum = (rand() % 10) + 1;
printf("\nGuess a number between 1 and 10:\n\n ");
scanf("%d", &iResponse);
if(!isdigit(iResponse)){
printf("\nThank you\n");
printf("\nYou entered %d\n", iResponse);
if(iResponse == iRandomNum){
printf("\nYou guessed right\n");
printf("\nThe correct guess is %d!\n", iRandomNum);
printf("\nDo you wish to continue? \n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
} else {
printf("\n\nSorry, you guessed wrong\n");
printf("\nThe correct guess was %d!\n", iRandomNum);
printf("\n\nDo you wish to continue? \n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
}
}
else {
printf("\nYou did not enter a digit\n");
printf("\n\nPlease enter a number between 1 and 10:\n\n");
scanf("%d", &iResponse);
}
}
else {
printf("\nThe window will now close. Try again later!\n");
exit(0);
}
}while(guessGame != NO);
}
The code goes into infinite loop as scanf() is unable to read an integer. The character you entered remains in the keyboard buffer.No more reading of integers is possible as long as the character is present in the buffer. scanf() simply returns the number of items read as 0 each time. Hence,the program does not wait for the user to enter data and infinite loop results.
scanf() returns number of items successfully read. So,you can simply check for the return value of scanf(), if its 1 then scanf() has correctly read an integer.
check = scanf("%d", &iResponse);
if(check == 1){
printf("\nThank you\n");
printf("\nYou entered %d\n", iResponse);
and flush the buffer if wrong input is entered
else {
while (getchar() != '\n'); //flush the buffer
printf("\nYou did not enter a digit\n");
printf("\n\nPlease enter a number between 1 and 10:\n\n");
//scanf("%d", &iResponse);
}
no need to ask for input here, while loop will continue and prompt for input in the beginning
Trying taking the input in the form of string .. also u will have to compare the input in the form 'number' :)

scanf asking for two values instead of one [duplicate]

This question already has answers here:
scanf() curious behaviour!
(3 answers)
Closed 8 years ago.
When I compile this code, it leads to scanf asking for a value twice when I pick choice A. What am I missing here?
This isn't the first time this is encountered, so I'm suspecting I'm failing to grasp something rather fundamental with scanf.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char choice;
printf("1. 'enter 'A' for this choice\n");
printf("2. 'enter 'B' for this choice\n");
printf("3. 'enter 'C' for this choice\n");
scanf("%c", &choice);
switch (choice)
{
case 'A':
{
int a =0;
printf("you've chosen menu A\n");
printf("enter a number\n");
scanf("%d\n", &a);
printf("%d\n", a);
}
break;
case 'B':
printf("you've chosen B\n");
break;
case 'C':
printf("you've chosen C\n");
break;
default:
printf("your choice is invalid\n!");
break;
}
return 0;
}
scanf("%d\n", &a); should be scanf("%d", &a);
Also read Related question.
In former case after reading an integer and storing into a, scanf's argument string is not exhausted. Looking at \n, scanf would consume all the whitespaces (newline, tab, spaced etc) it sees (And will remain blocked) until it encounters a non-whitespace character. On encountering a non-whitespace character scanf would return.
Learning: Don't use space, newline etc as trailing character in scanf. If the space character is in the beginning of argument string, scanf may still skip any number of white space characters including zero characters. But when whitespace is a trailing characters, it would eat your new line character also unless you type a non-whitespace character and hit return key.
Simply remove the newline character from scanf("%d\n", &a); and it will not ask to enter a value twice
scanf("%d", &a);
Remove a newline character while scanning
// the trailing '\n' in the scanf format string
// is what is causing the dual inputs
// the returned value from I/O statements (I.E. scanf)
// needs to be checked to assure operation was successful
#include <stdio.h>
#include <stdlib.h>
int main()
{
char choice;
printf("1. 'enter 'A' for this choice\n");
printf("2. 'enter 'B' for this choice\n");
printf("3. 'enter 'C' for this choice\n");
// note
// leading ' ' in format string to consume leading white space
// and no trailing '\n'
if( 1 != scanf(" %c", &choice) )
{ // then, scanf failed
// handle error condition
perror("scanf failed for choice");
exit(EXIT_FAILURE);
}
// implied else, scanf successful
switch (choice)
{
case 'A':
{ // braces needed due to variable declaration
int a = 0; // corrected ':' to ';'
printf("you've chosen menu A\n");
printf("enter a number\n");
// note
// leading ' ' in format string to consume leading white space
// and no trailing '\n'
if( 1 != scanf(" %d", &a) )
{ // then scanf failed
// handle error condition
perror("scanf failed for number");
exit(EXIT_FAILURE);
}
// implied else, scanf successful
printf("%d\n", a);
}
break;
case 'B':
printf("you've chosen B\n");
break;
case 'C':
printf("you've chosen C\n");
break;
default:
printf("your choice is invalid\n!");
break;
} // end switch
return 0;
} // end function: main

Resources