Windows command line EOF does not terminate input

The code:

#include <stdio.h> #define NEWLINE '\n' #define SPACE ' ' int main(void) { int ch; int count = 0; while((ch = getchar()) != EOF) { if(ch != NEWLINE && ch != SPACE) count++; } printf("There are %d characters input\n" , count); return 0; } 

Question:

  • Everything works fine, it ignores spaces and a new line and displays the number of characters entered on the screen (in this program I just process a comma, exclamation point, numbers or any printed character of a special character, such as an ampersand and a character too) when I hit EOF simulation, which is equal to ^z .

  • But something is wrong when I enter this line into the program. For example, I enter this: abcdefg^z , which means that I entered some character before and on the same line as ^z . Instead of ending the program and printing common characters, the program will continue to request input.

  • Entering the EOF termination character only works when I specify ^z on the same line or as follows: ^zabvcjdjsjsj . Why is this happening?

+7
source share
2 answers

This is true for almost every terminal driver. You will get the same behavior using Linux.

Your program does not actually loop until \n or ^z is entered by you at the end of the line. The terminal driver performs input buffering and is not sent to your process until this happens.

At the end of the line, pressing ^z (or ^d on Linux) does not cause the terminal driver to send EOF. It only makes it clear the buffer before your process (without \n ).

Pressing ^z (or ^d on Linux) at the beginning of a line is interpreted by the terminal as "I want to signal EOF."

This behavior can be observed if you add the following inside the loop:

 printf("%d\n",ch); 

Run the program:

 $ ./test abc <- type "abc" and hit "enter" 97 98 99 10 abc97 <- type "abc" and hit "^z" 98 99 

To better understand this, you must understand that EOF is not a character. ^z is a user command for the terminal itself. Since the terminal is responsible for entering user input and passing it on to processes, this becomes complicated and therefore confusing.

A way to see this is by pressing ^v and then pressing ^z as input to your program.

^v is another terminal command that tells the terminal: "Hey, the next thing I type is don't interpret this as a terminal command, and then pass it to the input of the process."

+14
source

^Z is passed to the console only by the EOF signal to the program when it is entered at the beginning of the line. This is how the Windows console works. There is no such “workaround” to this behavior that I know of.

+4
source

All Articles