这是C中的基本字符计数程序:
#include <stdio.h>
#include <stdlib.h>
int main(){
long nc = 0;
while(getchar() != EOF)
nc++;
printf("%ld\n" , nc);
}
Run Code Online (Sandbox Code Playgroud)
当我输入"abcde"作为输入时,它显示值6(触发EOF测试后),换行符字符+1.但我怀疑的是getchar(),正如其名称本身所暗示的那样,只考虑了1个字符.但是当我一口气进入"abcde"时,它仍然有效.为什么会这样?我在这做什么问题?
Cro*_*man 15
默认情况下,标准输入是使用交互式设备进行行缓冲的.这意味着你的程序在完成一行就绪之前根本不会看到任何输入,在你遇到的情况下Enter.一个很好的理由是,如果用户输入她的8个字符密码,然后按退格8次,然后输入她的用户名和点击数Enter,那么你的程序只获取她的用户名,并且永远不会看到更正,这通常是你想要的当你的shell在任何地方发送之前都有机会编辑你的输入.
所以发生的事情基本上就是这样
你打电话getchar().没有可用的输入,所以它等待.
你按a.这不是一行的结束,所以没有输入发送到你的程序,getchar()没有什么可读,所以它仍然等待.
你按b.这不是一行的结束,所以没有输入发送到你的程序,getchar()没有什么可读,所以它仍然等待.
你按c.这不是一行的结束,所以没有输入发送到你的程序,getchar()没有什么可读,所以它仍然等待.
你按d.这不是一行的结束,所以没有输入发送到你的程序,getchar()没有什么可读,所以它仍然等待.
你按e.这不是一行的结束,所以没有输入发送到你的程序,getchar()没有什么可读,所以它仍然等待.
你按Enter.现在它是一行的结尾,因此输入"abcde\n"被发送到您的程序.
getchar()现在有输入读取,所以它返回'a',递增nc和循环返回等待输入.
立即getchar()有更多输入从该行中的其余字符读取,因此它返回'b',递增nc和循环以等待输入.
立即getchar()有更多输入从该行中的其余字符读取,因此它返回'c',递增nc和循环以等待输入.
立即getchar()有更多输入从该行中的其余字符读取,因此它返回'd',递增nc和循环以等待输入.
立即getchar()有更多输入从该行中的其余字符读取,因此它返回'e',递增nc和循环以等待输入.
立即getchar()有更多输入从该行中的其余字符读取,因此它返回'\n',递增nc和循环以等待输入.
如果你指的是输入结束,也许是按Control- D,那么getchar()没有什么可读的,并且知道永远不会有任何东西要读,所以它返回EOF并且你的循环结束.如果它不是输入结束,那么getchar()将再次等待您输入新的输入行.
所以这里真正发生的事情就是getchar()在你击中之前什么也没做Enter.然后,可能在您将手指从Enter键上移开之前,它会运行六次并消耗您输入的六个输入字符.但是尽管getchar()运行了六次,你只会被提示输入一次(两次,如果你必须输入Control- D),因为getchar()只有当你的输入还没有可用的输入并等待时才会等待输入.
在独立终端常见的日子里,实际的终端设备甚至可能不会将任何字符传输到计算机直到线路末端,并且可能有少量的板载内存以允许这种本地线路 - 基于编辑,所以计算机本身可能永远不会看到它直到行尾.在许多人使用的现代PC上,操作系统,在终端驱动程序级别下,更可能是缓冲这些字符本身,只是呈现它们并一次一行地将它们提供给你的程序(除非你具体说明)告诉它你当然要立刻想要角色).
getchar从标准输入缓冲区读取下一个字符,然后返回它,因为您将六个字符 - “abcde\n” - 输入到标准输入中,并且您getchar在 while 循环中调用,这意味着循环体运行了六次,它一一读取字符。您可以通过以下方式进行测试:
int c;
while ((c = getchar()) != EOF) {
printf("got %c\n", c);
nc++;
}
Run Code Online (Sandbox Code Playgroud)