This kind of questions might seem as one of those geeky considerations, but I rather ask you for thorough explanation of what is going on to satisfy my curiosity.
Let's assume we have a following chunk of code:
#include <stdio.h>
int main(void)
{
char ch;
scanf("%c", &ch);
printf("%d\n", ch);
return 0;
}
After compilation, one can type at the beginning of line simulated EOF with CTRL+Z shortcut and press ENTER - this is done twice.
Output looks like this:
^Z
^Z
-52
Press any key to continue . . .
1) What is happening right now?
I have another doubt concerning such loop:
while (scanf("%c", &ch) != EOF)
printf("%c\n", ch);
printf("BYE!\n");
Output will be:
^Z
^Z
BYE!
Press any key to continue . . .
2) Why is not it terminating after first EOF simulation?
EDIT: I searched for another answers on SO relating to my doubts and I think that it is difficult to use scanf()
, as it has got better substitutes like fgets()
or fread()
. Please take a look on another example below:
int input;
char ch;
while (scanf("%d", &input) != 1) //checking for bad input
while ((ch = getchar()) != '\n') //disposing of bad input
putchar(ch);
printf("BYE!\n");
I input five times CTRL+Z at the beginning of line and the output would become:
^Z
^Z
^Z
^Z
^Z
^Z
^Z
^Z
^Z
^Z
^CPress any key to continue . . .
I added five more EOFs and had to kill program with CTRL+C on the last line.
3) Why the space appeared on the 5-th line and was visible to the end (sometimes two spaces are before '^CPress any key to continue . . .')?
Last example is amendment of loop from above (there is no meaning in code):
while (scanf("%d", &input) != EOF);
printf("BYE!\n");
Output is:
^Z
^Z
^Z
BYE!
Press any key to continue . . .
4) Why are we using three times CTRL+Z instead of two as it was written in above comment?
ch
so you get an indeterminate (semi-random) value printed forch
. (2) On Unix, if you indicated EOF (with Control-D, usually) as the first character of input, then you'd not need to repeat it; if you've typed a character, say a blank, and then type Control-D, that sends the blank to the program, but the programs continues to wait for a newline — or another EOF. If you're on Windows (plausible since you're using Control-Z rather than Control-D), the rules may be slightly different; you might have to indicate EOF twice always. – Jonathan Lefflerch
whenscanf("%c", &ch) != 1
as inscanf("%c", &ch); printf("%d\n", ch);
– chux - Reinstate Monicaabc
and then Control-Z once, the charactersabc
are made available to functions such asgetchar()
. Sincegetchar()
doesn't care about newlines, the code should printa
and then the loop-less code will exit. If you loop, the code will read the three characters and then wait for more input. If you type another Control-Z, the underlyingread()
system call returns 0 bytes available, which is the indication of EOF. If you use a line-based input (fgets()
or POSIXgetline()
), those won't return theabc
until either a newline or the EOF is read. – Jonathan Leffler