Quite often I see the following problem in people’s code ( as a matter of fact, aliens don’t do that mistake :p ), when trying to input a character again and again with scanf. Usually, this happens inside a loop, but let’s see a sample code without a loop that exposes the problem.
badCscanf.c
#include int main(void) { char c; printf("Input No.1\n"); scanf("%c", &c); printf("c = %c\n", c); printf("Input No.2\n"); scanf("%c", &c); printf("c = %c\n", c); printf("Input No.3\n"); scanf("%c", &c); printf("c = %c\n", c); return 0; }
which gives output
Input No.1 s c = s Input No.2 c = Input No.3 a c = a RUN SUCCESSFUL (total time: 5s)
As you see, the input No.2 was skipped. Well not really, not at all. But the intention of the programmer is usually to get three characters from the user, which is what is happening, isn’t? Let me explain. Think what you do, when you input. First prompt message arrives, you type s and then what? You hit enter! Enter is a character!
As a result, first scanf will read the s. Second scanf will read the enter! That’s why, the second printf of the value of c leaves just a newline after “c=”. Then the third scanf waits for a key press. You input a and then you hit enter. a is been assigned to variable c and enter remains in the stdin buffer, ready to be read by the next scanf. If we had a fourth scanf, then it would read the enter.
However, many would think now that, “Wait a minute… I do this while reading numbers, with %d for example and I had no problem”. Correct! Why? Because %d automatically eats whitespaces and special characters. Logical, isn’t it? Whitespaces and special characters are characters, not numbers! However, %c has to interpret whitespaces and special characters as inputs, because %c reads characters 😉 . Luckily enough, the “fix to scanf to do what you intend it to do” is to leave a space before %c. That way you say to scanf to automatically eat whitespaces and special characters, like enter! So, just change scanf(“%c”, &c); to scanf(” %c”, &c); and you will be just fine. See by yourself in the code bellow:
goodCscanf.c
#include int main(void) { char c; /* FIX: Leave a space before %c */ printf("Input No.1\n"); scanf("%c", &c); printf("c = %c\n", c); printf("Input No.2\n"); scanf(" %c", &c); printf("c = %c\n", c); printf("Input No.3\n"); scanf(" %c", &c); printf("c = %c\n", c); return 0; }
which outputs, what you expect:
Input No.1 s c = s Input No.2 a c = a Input No.3 m c = m RUN SUCCESSFUL (total time: 4s)
Notice that in the first scanf, there is no need for a space before %c, since it’s the first input function, thus there is no trailing newline to eat, as discussed in the comments section below my post.
I suggest taking a look at my relevant answer in Stackoverflow too.
This code was developed by me, G. Samaras. There is also a nice answer in this Stackoverflow question.
Have questions about this code? Comments? Did you find a bug? Let me know! 😀
Page created by G. (George) Samaras (DIT)
Pingback: How to do scanf for single char in C [duplicate]
very helpful Thanks
Glad it helped!
bro thank you so much. i been waiting for this solution past 3 days. finally you give a solution to my problem. you are the best
Glad I helped! Keep it up!
i love you dude!!
🤩
Very useful info. To avoid this problem, we can use “%s” rather “%c” which will overcome this issue.
Great!
Thank you
Glad it helped!
New to C and this was driving me crazy, thank you so much.
Glad it helped!
very helpful for my introduction of programming in my EE class. thanks dude 😀
You are welcome dwi!
TYSM. It really works but i do not understand why leave a space before %c can fix that problem. Can you explain more clearly?
Maybe this will help: https://stackoverflow.com/questions/17079144/why-we-need-to-put-space-before-c
Does fgets() have this problem or its just a problem with scanf()?
My code has the following structure and its modular.
first I used scanf() to read a character.
scanf(” %c”, &op);
After this I have a function that inputs a string using fgets like the following.
fgets(string, sizeof(string), stdin);
I put this function in a loop so that It will keep on taking inputs from the user until a user presses the enter key twice after entering a string.
The execution goes like I input a string and press enter for entering the next string. when I don’t want to enter anymore strings I just press enter twice. All of this worked perfectly well until I added a loop that preceeds this function.
This means that a trailing newline character remains in the STDIN buffer, waiting to be consumed. I suggest posting a Stack Overflow question if needed. Also, take a look here: https://stackoverflow.com/questions/34452945/what-is-the-meaning-of-trailing-newline-is-stripped
I vaguely understood that this might be what is happening and tried some things to solve it. As a last try I created a dummy char variable literally named dummy and wrote another scanf() function that can read this enter character waiting to be consumed into &dummy. And voila that was the final edit to my code and the exercise I took up weeks before finally came to completion.
Thank you so much for all the quick replies and the article.
Great news Manjunath! No worries, I took care of the redundant comments. 🙂