I write a piece of code to help myself understand how things work when stdin
and stdout
involved.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
void prompt(){
int i=0;
printf("please select:\n"); //string1
printf("1.input\n2.print\n3.Exit\n"); //string2
scanf("%d",&i);
switch(i){
case 1:
printf("Data input!\n");
break;
case 2:
printf("data printed!\n");
break;
case 3:
exit(0);
case 10:
printf("Newline detected!"); //string3
default:
printf("Please input a valid number!(1-3)"); //string4
}
}
int main()
{
while(1)
prompt();
return 0;
}
What I expect this code to do is:
- prompt me for input;
- then I enter a number 4,which is out of the cases;
- so the default case will be matched and the string 'Please input a valid...'(string 4) will be printed.
- as there is still a newline character left in the stdin buffer, in the next loop, the variable 'i' will automatically get a newline character, which is 10 in ACSII
- So after printing out 'please select..1.input\n2.print....',, a string 'Newline detected!'(string 3) will be immediately printed out.
- And then the code goes into the third loop, and prompt me for input....
But that never happen. I cannot see any 'Newline detected!" in the output even if I enter a number 4, which is out of the cases.
Anyone can elaborate how this snippet work exactly?
By the way: I originally assume that when there is something printed in the stdout, the stdin buffer will be flushed automatically. But some fact proved me wrong. Is my assumption true or false?
Also, when I enter a character(for example, a g
) rather than a number, I got string 1, string 2, sring 4 printed in the screen infinitly. Why is that?
Edit: After viewing the answer, I make another snippet, to help understand.
#include<stdio.h>
#include<stdlib.h>
void output();
int main()
{
int i;
printf("Enter a number here:\n");
scanf("%d",&i);
output();
return 0;
}
void output(){
char a;
if (scanf("%c",&a)!=1){
printf("scanf error!!");
exit(1);
}
switch(a){
case 'a':
printf("an char a is entered");
break;
case 'b':
printf("an char b is entered");
break;
default:
printf("%c",a);
printf("other thing is entered");
}
}
whatever you enter the first time the program prompt you, you will never get your second prompt. For example, when the program prompt you for the first time, if you enter a number 4, then you will get a newline and a string "other thing is entered" printed on you screen. Why is that?
Addressing the second program in the question, here's a mildly revised version. It prints more information, and uses strict prototypes.
Example runs:
Note that in the first run, the stray character is the newline after the second
1
digit, character code 10. This is what you should get.Do make sure your output print operations end with a newline (so that it appears in a timely manner). If you don't, your output may be held up indefinitely.
The
scanf("%d", &i)
certainly doesn't. Thescanf("%c", &a)
does. Whenscanf()
completes a conversion, it puts the character that is not part of the conversion back into the input stream ready for the next input operation. So, it doesn't matter whether there's a space, a letter or a newline after the number, that character is left ready for the next input operation to read it. Mostscanf()
operations skip leading white space. There are three exceptions:%c
,%n
and%[…]
(scansets). They do not skip leading white space.