Windows命令提示符下的EOF不会终止inputstream
码:
#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; }
题:
-
一切正常,它会忽略空格和换行符,并输出input到屏幕上的字符数(在这个程序中,我只是把逗号,感叹号,数字或任何可打印的特殊符号字符如&符号作为字符) EOF模拟是
^z
。 -
但是当我把这一行input到程序中时有什么问题。 例如我input这个:
abcdefg^z
,这意味着我input一些字符之前,并在同一行^z
。 程序不是终止程序并打印出全部字符,而是继续要求input。 -
EOF终止字符input仅在单行指定
^z
时才起作用,或者这样做:^zabvcjdjsjsj
。 为什么发生这种情况?
几乎每个terminal驱动程序都是如此。 你会得到使用Linux相同的行为。
你的程序实际上并没有执行循环,除非你在行尾input了\n
或^z
。 terminal驱动程序正在缓冲input,直到发生这种情况才被发送到您的进程。
在一行的结尾处,点击^z
(或Linux上的^d
)不会导致terminal驱动程序发送EOF。 它只是使冲洗到你的过程缓冲区(没有\n
)。
在行的开始处打到^z
(或Linux上的^d
)被terminal解释为“我要发信号EOF”。
如果在循环中添加以下内容,可以观察到这种行为:
printf("%d\n",ch);
运行你的程序:
$ ./test abc <- type "abc" and hit "enter" 97 98 99 10 abc97 <- type "abc" and hit "^z" 98 99
为了更好地理解这一点,你必须认识到,EOF不是一个字符。 ^z
是terminal本身的用户命令。 由于terminal负责接收用户input并将其传递给进程,这会变得棘手,从而造成混乱。
看到这个的方法是按^v
然后点击^z
作为程序的input。
^v
是告诉terminal的另一个terminal命令,“嘿,我input的下一个东西 – 不要把它解释为terminal命令,而是把它传递给进程的input”。
^Z
仅在控制台转换为EOF信号时才会在程序的开头input。 这只是Windows控制台的工作方式。 对于我所知道的这种行为没有“解决方法”。