这是C中的基本字符计数程序:
getchar()
当我进入" abcde"作为输入,它显示值6(触发EOF测试后),换行符的+1。但我怀疑function(){}()
正如其名称本身所暗示的那样,只考虑了1个字符。但是当我进入" abcde"一气呵成,它仍然有效。为什么会这样?我在这做什么问题?
答案 0 :(得分:13)
默认情况下,标准输入是使用交互式设备进行行缓冲的。这意味着您的程序在完成一行准备就绪之前根本看不到任何输入,在您点击 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上,操作系统,在终端驱动程序级别下,更可能是缓冲这些字符本身,只是呈现它们并一次一行地将它们提供给你的程序(除非你具体说明)告诉它你当然要立刻想要角色。
答案 1 :(得分:3)
当您输入abcde\n
(从 Enter 生成的\n
)时,它会被刷新到标准输入流(stdin
)。
getchar()
,正如其名称本身所暗示的,只占用一个字符
是的,没错。但请注意getchar
用于循环,循环直到getchar
返回EOF
。另请注意,getchar
从stdin
读取输入。
因此,在第一次迭代中,在您输入数据后,getchar
会读取第一个字符a
。在第二次迭代中,它不会等待输入,因为stdin
仍然包含bcde\n
,因此会读取下一个字符b
,依此类推。
最后,当您触发EOF
时,循环会中断。然后,执行printf
(打印6
,因为读取了六个字符),程序结束。
答案 2 :(得分:0)
getchar
从标准输入缓冲区中读取下一个字符并返回它,因为您将6个字符 - “abcde \ n” - 输入标准输入,并在while循环中调用getchar
,这意味着循环体运行了六次,它逐个读取字符。您可以通过以下方式测试:
int c;
while ((c = getchar()) != EOF) {
printf("got %c\n", c);
nc++;
}