scanf asking for two values instead of one [duplicate] - c

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

Related

Next printf comes before my scanf takes input

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.

Code fails at case '0' - I don't understand why

Here is a minimal form of the code emphasizing the issue I have.
Code fails at "exit"(case '0') - program simply crashes. I suspect it is related to the while loop.
The issue occurs no matter what character i choose for the exit case (instead of '0').
#include <stdio.h>
void main()
{
int run=1;
char menu_option;
while (run==1)
{
printf("Choose case:\n");
scanf ("%s", &menu_option);
switch (menu_option) {
case '1':
printf("1");
break;
case '2':
printf("2");
break;
case '0':
run=0;
break;
default:
printf("Wrong input, try again\n");
}
}
}
menu_option is not a string, so %s is the wrong format specifier. You need %c, prefixed with a space to prevent whitespace (including newline) being interpreted as valid character input.
scanf (" %c", &menu_option);

switch statement creating infinite loop

I am writing a piece of code and in one part of my code I am using a switch statement in C language. if I press n it exits correctly if I press y it will infinite loop the default statement until I press control c. what am I doing wrong here. been changing the while statement but can't find the right one.
int main()
{
char ans;
printf("DO you want to continue?");
scanf("%c", &ans);
do
{
switch(ans)
{
case 'y':
some stuff...
printf("DO you want to continue?");
scanf("%c", &ans);
break;
case'n':
printf("BYE");
break;
default:
printf("error, you must enter y or n");
continue;
}
}
while (ans!='n');
return 0;
}
When you press enter, the linefeed character \n is added to the input stream. Your code does not anticipate this, because switch(ans) only handles y, n or “everything else” (which includes the linefeed character).
To fix this, allow scanf to ignore any preceding whitespace by changing your format string to " %c" instead, e.g.
scanf(" %c", &ans);
// ^ space character inserted here
I think it would make more sense to move the scanf call to inside the loop, like this:
int main()
{
char ans;
do
{
printf("DO you want to continue?");
if (scanf(" %c", &ans) != 1)
break;
switch(ans)
{
case 'y':
// some stuff...
break;
case 'n':
printf("BYE");
break;
default:
printf("error, you must enter y or n");
continue;
}
}
while (ans!='n');
}
Don't forget to always check the result of scanf(). It will return the number of items successfully scanned (in your case, you want it to return 1). If it returns 0 or a negative number, then another problem has occurred.

I cannot seem to loop again after selecting default in switch case in C

hello guys I coded something like kfc menu,and I got it to work(finally),but when I input something other than numbers for "menu",eg:the letter "A", I just can't get it to loop again to normal,instead it finishes the program
#include <stdio.h>
#include <stdlib.h>
int main()
{
char counter='y';
float totalprice=0;
while (counter=='Y' || counter=='y')
{
int menu;
float price=0;
printf("\nplease select from menu:");
scanf (" %i", &menu);
switch(menu)
{
case 1: {
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
}
case 2: {
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
}
case 3:{
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
}
default : {
printf ("\nplease enter proper number please:");
scanf("%2f", &menu);
break;
}
}
printf("\n\nadd order?(Y/N):");
scanf (" %c", &counter);
}
printf("\n\nThe total price is: %f", totalprice);
return 0;
}
You should use fgets() (reference here) first and then sscanf() (reference here), checking it's return value to see if it's a number.
char inputBuffer[MAX_BUFFER];
do
{
fgets(inputBuffer, MAX_BUFFER, stdin);
}
while(sscanf(inputBuffer, "%d", &menu) != 1)
You scanf with %f in the default case, I am fairly certain that is for floats. Use %d.
Remove scanf("%2f", &menu);
Switch in C does not support char in switch-case. Before you start switch-case validate the user input. If it is a number go into switch case otherwise display a user message to enter only numeric value
I recommend that you debug this by printing out the value of "counter" at various points in the loop (i.e. after you read it in, at the bottom of the loop, etc.). This will give you visibility into what your code is doing.
You can try something like this
#include <stdio.h>
int main()
{
char counter;
float totalprice=0;
int menu=0;
do
{
printf("\n1. one hotbox1=RM10.50");
printf("\n2. one hotbox2=RM10.60");
printf("\n3. one hotbox3=RM10.70");
printf("\nplease select from menu:");
scanf ("%d", &menu);
switch(menu)
{
case 1:
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
case 2:
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
case 3:
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
default :
printf ("\nplease enter proper number please:");
scanf("%d", &menu);
}
printf("\n\nadd more order?(Y/N):");
fflush(stdin); //to empty the input stream.
scanf("%c",&counter);
}while(tolower(counter) != 'n'); //tolower returns the lowercase character.
printf("\n\nThe total price is: %.2f", totalprice);
return 0;
}
When scanf("%i", &menu) tries to read an integer from the input, it finds A, which it cannot interpret as a number, so it does not read it(*). Then the next scanf continues reading the input from when the other left off and happily reads the letter 'A'. Since you loop as long as the read letter is either 'y' or 'Y' (which A is neither), it exits the loop.
(*) read up on the documentation of scanf to see how to tell if it encountered an error.
Note: scanf("%i", &menu) should be scanf("%d", &menu) as%d` is the formatting symbol for integers.
One solution would be to change the loop condition to:
while (counter!='N' && counter!='n')
{
...
}
This way you end the loop only if an explicit 'N' or 'n' is inputted.
Note: it won't help if you accidentally type 'n' for the menu item, so see the comment about the error handling above.

My program is not asking for the operator the second time

#include<stdio.h>
#include<stdlib.h>
main(){
int b,c,r,d;
char a;
while(1){
printf("Enter the operator\n");
scanf("%c",&a);
if(a=='+') d=1;
if(a=='-') d=2;
if(a=='&') d=3;
if(a=='|') d=4;
if(a=='.') d=5;
printf("Enter the operands\n");
scanf("%d",&b);
scanf("%d",&c);
switch(d){
case 1:r=c+b;
break;
case 2:r=c-b;
break;
case 3:r=c&b;
break;
case 4:r=c|b;
break;
case 5:exit(0);
deafult:printf("Enter a valid operator");
}
printf("Result = %d\n",r);
}
}
Output:
Enter the operator
+
Enter the operands
8
7
Result = 15
Enter the operator
Enter the operands
scanf("%d",... will read a number (skipping whitespace beforehand) but leave the newline on the input stream. scanf("%c",... will read the first character, and does not skip whitespace.
One simple modification is to use
scanf(" %c", &a);
This will tell scanf to skip any whitespace before the character.
That because of the function scanf width param "%c", after the 1st time loop, at line scanf("%d",&c);, like +, there's a end-line character in the input stream, then the second loop, scanf get the end-line character as the input and parse it to a;
To fix this, you can add a scanf("%c"); line right after scanf("%d",&c);
have a look at
scanf error in c while reading a character

Resources