Search code examples
cwindowsstdineof

Stdin and EOF Behaviour under Windows console


I'm learning how input works in C. My biggest struggle is understanding EOF behaviour in the terminal
First, i'm using Windows and GCC compiler "In case this might help"
Second, i'm not trying to redirect input from a file... my question is about input from Windows console

My question:

I read that EOF closes the input stream, that you can't read from stdin after EOF... This is not the case for me! Even after i enter explicitly Enter-Ctrl-Z-Enter, if i do another getchar() call it reads from stdin... An example:

int c = 0;
char str[100]={0};

printf("Type in a string with spaces so some chars would remain in Stdin: ");
//Let's say i type "Hello world!"
scanf("%s",str);

while( (c=getchar()) != EOF )
    printf("%c",c);
//it displays " World!" in console, then i type Enter-^Z-Enter
//The loop exits so far so good

printf("Let's just check if we can still read from stdin, type a char: ");
c = getchar(); //i type the letter 'a'
printf("\nYou entered: %c\n",c); //It displays 'a'?!


Also, something strange happens when you type ^Z in the middle of string, any chars before it would be returned but anything typed after it disapprears! But when you check for the variable content it's not equal to -1? Here's an example:

int c = 0;
char str[100]={0};

printf("Type in a string with spaces so some chars would remain in Stdin: ");
//This time i type "Hello wor^Zld!" with ^Z in the middle of "World!"
scanf("%s",str);    

while( (c=getchar()) != EOF )
    printf("%c",c);
//it displays " Wor->" in console, with the cursor hanging waiting for input
/*
So on the one hand, after ^Z everything disappears, but on the other 
hand it's waiting for input so it's not EOF?!
*/

//In case you're wondering, here too i can call getchar() and read from stdin!
printf("Let's just check if we can still read from stdin, type a char: ");
c = getchar(); //i type the letter 'a'
printf("\nYou entered: %c\n",c); //It also displays 'a'?!


Believe me i'm really trying to understand how this works but it's really confusing for a beginner in C... So any help would be greatly appreciated!


Solution

  • You use Ctrl-Z to signal EOF. Your program behaves accordingly. But stdin will remain open. You can still 'close' stdin, but for your program only. Try this, and see the difference:

       while ((c = getchar()) != EOF)
          printf("%c", c);
       fclose(stdin); // <----------
       printf("Let's just check if we can still read from stdin, type a char: ");
       c = getchar();
       printf("\nYou entered: %c\n", c);
    

    You will not get 'a' anymore, you will get EOF (-1).


    Edit:

    • EOF is a macro definition in stdio.h, and is commonly equal to -1
    • To simulate EOF via terminal input, type the sequence: Enter-Cntrl-Z-Enter in the Windows console.
    • After EOF signal, the input stream remains open... Why? Because stdin is supposed to be always open. (One could use fclose(stdin) to close the stream, but that is a bad idea, since file handles can easily get messed up.)
    • ^Z is not EOF, if you check for it's value it's 26 (Not -1).
    • Typing ^Z anywhere would flush stdin after that...