Unable to read the char input in C using %c - c

#include <stdio.h>
#include <stdlib.h>
int main()
{
int num1;
int num2;
char op;
printf("Enter the first number: ");
scanf("%d", &num1);
printf("Enter an operator: ");
scanf("%c", &op);
printf("Enter the second number: ");
scanf("%d", &num2);
switch(op){
case'+':
printf("%d", num1+num2);
break;
case'-':
printf("%d", num1-num2);
break;
case'/':
printf("%d", num1/num2);
break;
case'*':
printf("%d", num1*num2);
break;
default:
printf("Enter a valid Operator");
}
return 0;
}
I tried to build a basic calculator with user input. but I am getting an error in this line scanf("%c", &op); I searched in here(Stackoverflow) and I also found the answer that if I put a space in scanf(" %c", &op) then my program will work fine;
now the question I have is, Could someone explain me this in laymen's terms for a beginner? Please. Your answer will be much appreciated

scanf manual:
specifier c:
Matches a sequence of characters whose length is specified by the
maximum field width (default 1); the next pointer must be a pointer to
char, and there must be enough room for all the characters (no
terminating null byte is added). The usual skip of leading white space
is suppressed. To skip white space first, use an explicit space in the
format.
ie format scanf(" %c", &op).
After typing the first number for int num1 you type an enter '\n' the next scan for character captures the new line and prints it . So as per the manual, To skip white space first, use an explicit space in the format:
printf("Enter an operator: ");
scanf(" %c", &op);
or use like this below:
printf("Enter an operator: ");
scanf("%c", &op);
scanf("%c", &op);

Prepend the conversion specifier in the format string with a space like
scanf( " %c", &op );
^^^^^
In this case white space characters in the input stream as the new line character '\n' that corresponds to the pressed key Enter will be skipped

The problem is not with scanf but stdin. stdin and stdout refer to the same file in the memory for console application. So there is '\n' in the stdin which you have entered for first scanf which is taken by scanf and stored in op. Try putting scanf("%c", &op); above scanf("%d", &num1); or write fflush(stdin) above scanf("%c", &op);

Try using 'getc' and 'gets' instead.
'scanf' is considered to be unsafe altogether and it would be wise to search for safer alternatives. That way you will have greater control over user input.

Related

What is the purpose of this dummy variable variable and why program exits without it in c? [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed last month.
int main ()
{
char c;
int choice,dummy;
do{
printf("1. Print Hello\n2. Print World\n3. Exit\n");
scanf("%d",&choice);
switch(choice)
{
case 1 :
printf("Hello\n");
break;
case 2:
printf("World\n");
break;
case 3:
exit(0);
break;
default:
printf("please enter valid choice\n5");
}
printf("do you want to enter more?");
scanf("%d",&dummy);
scanf("%c",&c);
}while(c=='y');
}
tried removing int dummy variable and dummy input, program exits without taking any character input. how is this helping the code to not to exit ?
Whoever wrote this doesn't understand how scanf format specifiers work.
The first call to scanf uses the %d format specifier. This reads and discards any leading whitespace, then reads a decimal integer. Assuming you pressed ENTER after typing in this integer, a newline character will be left in the input buffer.
The %c format specifier reads the first character in the input buffer but does not strip off trailing whitespace. So without the prior call reading dummy, this will read the newline that was stuck in the input buffer previously into c. That causes the comparison c=='y' to be false so the loop exits..
The extra call to scanf for dummy reads and discards the newline left in the input buffer and wait for an integer to be read. Presumably, the user will enter y or n given the prompt, so that call to scanf will not read anything more and will return 0, indicating that nothing matched. The following scanf then reads the y or n.
The proper way to handle this is to add a space before the %c format specifier to absorb leading whitespace instead of adding a "dummy" call:
printf("do you want to enter more?");
scanf(" %c",&c);
The scanf("%d",&dummy) removes a newline so the subsequent scanf("%c",&c); works. Otherwise, it will take \n as its character.
The "extra" newline comes from the fact that it is left in the input stream by the original: scanf("%d",&choice);
To fix, remove the dummy related code and do:
scanf(" %c",&c);
Note the preceding space in the format. This tells scanf to skip over whitespace (which includes newlines).
The fully corrected code is:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char c;
int choice;
do {
printf("1. Print Hello\n2. Print World\n3. Exit\n");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Hello\n");
break;
case 2:
printf("World\n");
break;
case 3:
exit(0);
break;
default:
printf("please enter valid choice\n5");
}
printf("do you want to enter more?");
scanf(" %c", &c);
} while (c == 'y');
return 0;
}

why can't I input a character with scanf

why is this not working? im new to C...
the scanf function works just fine with other data types, its just the char thats not giving me the option to input a character
char grade;
printf("Enter your grade: ");
scanf("%c", &grade);
printf("Your grade is %c", grade);
It seems before entering the character there are inputs of other objects in your original program.
In this case you need to write
scanf(" %c", &grade);
Pay attention to the blank before the conversion specifier %c. It allows to skip white space characters.

Why is the scanf() skipped?

#include <stdio.h>
int main() {
char opt;
scanf(" %c", &opt);
switch (opt) {
case 'A':
printf("Please Enter a New Name:");
char name[200];
scanf("%[^\n]s", name);
printf("Please Enter a New Code:");
char code[200];
scanf("%s", code);
printf("Please Enter the Number:");
int number;
scanf("%d", number);
printf("%s\n%s\n%d", name, code, number);
printf("\nPlease press Enter to confirm Creation");
}
}
Why is the scanf of the name skipped? the output looks like
A
Please Enter a New Name:Please Enter a New Code:
Also when switch() is removed, it works normally. Is the problem on the switch()? It does not have other cases because it is an unfinished code.
As commented by melonduofromage, your first scanf leaves the newline (\n) typed by the user after the A in the input stream. Next scanf("%[^\n]s", name) fails because the first byte from the input stream is a newline, so scanf returns immediately with a return value of 0, which you should not ignore. The program then prompts for the code and scanf skips initial white space, including the pending newline and waits for user input.
To fix this problem, add a space before the conversion specifier to skip initial white space. You should also limit the number of characters stored into the destination array: specify this number between the % and the [. Note also that the trailing s in "%[^\n]s" is useless: it is not part of the conversion specifier and scanf() will try and match it against the input stream. The correct format is scanf(" %199[^\n]", name) and the return value must be 1 for a successful conversion.
Also note that there is a missing & in scanf("%d", number): you must pass the address of the destination variable: scanf("%d", &number);
Here is a modified version:
#include <stdio.h>
int invalid_input(void) {
fprintf(stderr, "invalid or missing input\n");
return 1;
}
int main() {
char opt;
if (scanf(" %c", &opt) != 1)
return invalid_input();
switch (opt) {
case 'A':
printf("Please Enter a New Name:");
char name[200];
if (scanf(" %199[^\n]", name) != 1)
return invalid_input();
printf("Please Enter a New Code:");
char code[200];
if (scanf("%199s", code) != 1)
return invalid_input();
printf("Please Enter the Number:");
int number;
if (scanf("%d", &number) != 1)
return invalid_input();
printf("%s\n%s\n%d", name, code, number);
printf("\nPlease press Enter to confirm Creation");
//...
}
return 0;
}
When you prompt user with the first scanf here
char opt;
scanf(" %c", &opt);
When the user enters a character, say A, "A\n" is placed in the buffer, \n coming from the user hitting the return key. The scanf takes one character as requested with the " %c" format string, and leaves the \n on the buffer.
When the second scanf is executed as
printf("Please Enter a New Name:");
char name[200];
scanf("%[^\n]s", name);
the format string "%[^\n]s" requests it to read until a \n is encountered, mind you, your buffer already contains a \n as the first character, hence scanf returns without reading anything, still leaving the \n in the buffer.
When the third scanf is executed as:
printf("Please Enter a New Code:");
char code[200];
scanf("%s", code);
(Corrected after the comments of chqrlie)
The format string "%s" ignores the leading whitespaces, hence now the \n is ignored, and scanf happily waits for your input.
Notice the leading space in the format string " %c", the space is there to get scanf ignore the leading whitespace, you can implement the same logic with your second scanf. You can either ensure that all consecutive scanf ignore the \n left in the buffer, which turns out most format specifiers do, or you can ensure that no scanf leaves it to begin with with using something like "<...>%*c" to get rid of it. Though none of which are reliable and consistent methods, and as said countless times, scanf is not designed to perform such tasks like taking user input, and you should seek alternative methods.
Also, the s in "%[^\n]s" certainly doesn't do what you expect. man page of the scanf states that
An ordinary character (i.e., one other than white space or '%'). This character must exactly match the next character of input.
If it matches, scanf discards it and continues parsing according to the remaining format specifiers. If it doesn't, scanf stops there and returns. Since it is at the end of your format string, it returns either way, hiding a potential bug from you.

Problems with scanf

#include <stdio.h>
int main()
{
char C, B;
int x;
printf("What comes after G\n");
scanf("%c", &C);
printf("What comes after O\n");
scanf("%c", &B);
printf("What is your age?\n");
scanf("%d", &x);
printf("You said %c comes after G, %c after T and you're %d years old? Right?", C, B, x);
return 0;
}
The problem is whenever you run the code it skips the second question "What comes after O" and then asks "What is your age?"
The only way I could avoid the program skip the 2nd question was by adding a space to the code
printf("What comes after O\n");
scanf(" %c", &B);
You can see the space between " and %c
Can you please explain this to me?
You need to eat up the white space (i.e. new line) - as per the manual page http://linux.die.net/man/3/scanf
You can use scanf to eat the single character without assigning it to anything like this::
scanf( "%[^\n]%*c", &C ) ;
%[^\n] tells the scanf to read every character that is not '\n'. That leaves the '\n' character in the input buffer, then the * (assignment suppression) will consume the a single character ('\n') but would not assign it to anything.
The reason for this problem is newline character \n leftover by the previous scanf after pressing Enter. This \n is left for the next call of scanf.
To avoid this problem you need to place a space before %c specifier in your scanf.
scanf(" %c", &C);
...
scanf(" %c", &B);
...
scanf(" %c", &X);
A space before %c is able to eat up any number of newline characters.
The problem is you are using scanf to get the character ..and a new line will be added at the end of each input from user . So the second time only the new line will be stored in the 'B' Because of the first input given by you ..
Instead of scanf , change it to getchar - your problem should get solved

problem in scanning character in C

#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
char ch;
printf("Enter value of a and b");
scanf("%d %d",&a,&b);
printf("Enter choice of operation");
scanf("%c",&ch);// **Here this statment is not able to receive my input***
switch(ch)
{
case '+':
c=a+b;
break;
case '-':
c=a-b;
break;
default:
printf("invalid");
break;
}
getch();
}
Error:
scanf("%c",&ch); // Here this statment is not able to receive my input
Unable to scan input given by user??????
thanks..
Unlike most conversions, %c does not skip whitespace before converting a character. After the user enters the two numbers, a carriage return/new-line is left in the input buffer waiting to be read -- so that's what the %c reads.
Just try
scanf(" %c", &ch);
This is because your scanf is treating the whitespace after the second number as the character to be inserted into ch.
It's getting the newline character from your previous data entry. Look into using fgets() and sscanf() instead of using scanf() directly.
Here in this statement write %s instead of %c. It will surely work.
scanf("%s",&ch);
in this problem you can write like this
scanf(" %c",&ch);
a space will cover your "Enter" character,then it scan's the input that you want...https://ide.geeksforgeeks.org/ANGPHrqeAq
If you're just reading in a single character, you could just use getchar() -
c = getchar();
Use getchar() or sscanf() whichever comforts more.
Like
char ch;
ch = getchar();
This is simple. also if you want to use scanf("%c",&ch); then,
just remove the \n from your previous printf() statement.
For a single character input, use getchar().

Resources