`getchar()`在哪里存储用户输入?

我开始阅读“ C编程语言 ”(K&R),我对getchar()函数有疑问。

例如这段代码:

 #include  main() { int c; c = getchar(); putchar(c); printf("\n"); } 

键入toomanychars + CTRL + D (EOF)只打印t 。 我认为这是预期的,因为它是第一个引入的角色。

但接下来是另一段代码:

 #include  main() { int c; while((c = getchar()) != EOF) putchar(c); } 

键入toomanychars + CTRL + D (EOF)打印toomanychars

我的问题是,如果我只有一个char变量,为什么会这样? 其余的字符存储在哪里?

编辑:

感谢大家的答案,我现在开始明白……只有一个问题:

当给定CTRL + D时,第一个程序退出,而第二个程序打印整个字符串,然后等待更多用户输入。 为什么它等待另一个字符串并且不像第一个那样退出?

它将输入流视为文件。 就好像你打开了一个包含文本“toomanychars”的文件,并一次读取或输出一个字符。

在第一个例子中,在没有while循环的情况下,就像你打开一个文件并读取第一个字符,然后输出它。 然而,第二个示例将继续读取字符,直到它获得文件结束信号(在您的情况下为ctrl+D ),就像它从磁盘上的文件读取一样。


在回复您更新的问题时,您使用的操作系统是什么? 我在我的Windows XP笔记本电脑上运行它,它工作正常。 如果我按下回车键,它会打印出我到目前为止的内容,换行,然后继续。 ( getchar()函数在你按下回车之前不会返回,这是在调用输入缓冲区时没有任何内容的情况下)。 当我按CTRL+Z (Windows中的EOF)时,程序终止。 请注意,在Windows中,EOF必须位于其自己的行上才能在命令提示符中计为EOF。 我不知道这种行为是否在Linux或任何你可能正在运行的系统中被模仿。

getchar从标准输入中获取单个字符,在本例中是键盘缓冲区。

在第二个示例中, getchar函数处于while循环中,该循环一直持续到遇到EOF ,因此它将保持循环并检索字符(并将字符打印到屏幕),直到输入变为空。

getchar连续调用将获得来自输入的连续字符。

哦,不要因为问这个问题而感到难过 – 当我第一次遇到这个问题时,我感到很困惑。

这里的东西是缓冲的。 例如,putchar写入的stdout FILE *可能是line.buffered。 当程序结束(或遇到换行符)时,这样的FILE *将被fflush()编辑,你会看到输出。

在某些情况下,您正在查看的实际终端可能会缓冲输出直到换行,或者直到终端本身被指示刷新它的缓冲区,这可能是当前前程序退出时它想要提示新提示的情况。

现在,这里的实际情况可能是,它是缓冲的输入(除了输出:-))当你按下它时,它会出现在你的终端窗口上。 但是终端不会将这些字符发送到您的应用程序,它将缓冲它,直到您使用Ctrl + D指示它是输入结束,并且可能还有换行符。 这是另一个版本,可以思考:

 int main() { int c; while((c = getchar()) != EOF) { if(c != '\n') putchar(c); } return 0; } 

尝试为程序提供一个句子,然后按Enter键。 如果你注释掉(c!=’\ n’)也可以这样做。也许你可以确定你的输入,输出或两者是否以某种方式缓冲。 如果你像上面那样运行它会变得更有趣:./ mytest | ./mytest

(另请注意,CTRD + D不是字符,也不是EOF。但在某些系统上,它会导致关闭输入流,这会再次将EOF提升给试图从流中读取的任何人。)

您的第一个程序只读取一个字符,打印出来然后退出。 你的第二个程序有一个循环。 它一直一个字符地读取并打印出来直到它读取EOF字符。 在任何给定时间只存储一个字符。

您只使用变量c包含一个字符。

一旦使用putchar(c)显示了第一个char( t ),就会通过将下一个字符( o )分配给变量c ,替换之前的值( t )来忘记c的值。

代码在function上等同于

 main(){ int c; c = getchar(); while(c != EOF) { putchar(c); c = getchar(); } } 

您可能会发现此版本更易于理解。 将赋值放在条件中的唯一原因是避免必须两次输入’c = getchar()’。

对于更新的问题,在第一个示例中,只读取一个字符。 它永远不会达到EOF。 程序终止,因为在完成printf指令后没有任何操作可做。 它只读一个字符。 打印出来。 放入换行符。 然后终止,因为它没有更多的事要做。 它不会读取多个字符。

然而,在第二个代码中,getchar和putchar存在于while循环中。 在此,程序继续逐个读取字符(因为它是通过循环这样做),直到达到EOF字符(^ D)。 此时,它匹配c!= EOF,并且由于不满足条件,因此它从循环中出来。 现在没有更多的语句可以执行了。 所以程序终止于此。

希望这可以帮助。