我开始阅读“The C Programming Language”(K& R),我对getchar()
功能有疑问。
例如这段代码:
#include <stdio.h>
main()
{
int c;
c = getchar();
putchar(c);
printf("\n");
}
键入toomanychars
+ CTRL + D (EOF)仅打印t
。我认为这是预期的,因为它是第一个引入的角色。
然后是另一段代码:
#include <stdio.h>
main()
{
int c;
while((c = getchar()) != EOF)
putchar(c);
}
键入toomanychars
+ CTRL + D (EOF)会打印toomanychars
。
我的问题是,如果我只有一个char变量,为什么会这样?其余的字符存储在哪里?
修改
感谢大家的答案,我现在开始明白......只有一个问题:
第一个程序在给出 CTRL + D 时退出,而第二个程序打印整个字符串然后等待更多用户输入。为什么它等待另一个字符串并且不像第一个字符串那样退出?
答案 0 :(得分:9)
getchar
从标准输入中获取单个字符,在本例中为键盘缓冲区。
在第二个示例中,getchar
函数位于while
循环中,一直持续到遇到EOF
,因此它将继续循环并检索一个字符(并打印字符)屏幕)直到输入变空。
对getchar
的连续调用将获得来自输入的连续字符。
哦,问这个问题也不错 - 当我第一次遇到这个问题时,我很困惑。
答案 1 :(得分:5)
它将输入流视为文件。就好像你打开了一个包含文本“toomanychars”的文件,并一次读取或输出一个字符。
在第一个例子中,在没有while循环的情况下,就像你打开一个文件并读取第一个字符,然后输出它。但是,第二个示例将继续读取字符,直到它获得文件结束信号(在您的情况下为ctrl+D
),就像从磁盘上的文件读取一样。
在回复您更新的问题时,您使用的操作系统是什么?我在我的Windows XP笔记本电脑上运行它并且工作正常。如果我按下回车键,它会打印出我到目前为止的内容,换行,然后继续。 (在您按下回车键之前,getchar()
函数不会返回,这是在调用输入缓冲区时没有任何内容的情况下)。当我按CTRL+Z
(Windows中的EOF)时,程序终止。请注意,在Windows中,EOF必须位于其自己的行上才能在命令提示符中计为EOF。我不知道这种行为是否在Linux或任何你可能正在运行的系统中被模仿。
答案 2 :(得分:4)
这里的东西是缓冲的。例如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键。如果你发表评论,也要这样做 if(c!='\ n')也许您可以确定您的输入,输出或两者是否以某种方式缓冲。 如果你运行上面这样会变得更有趣: ./mytest | ./mytest
(另请注意,CTRD + D不是字符,也不是EOF。但在某些系统上,它会导致关闭输入流,这会再次将EOF提升给试图从流中读取的任何人。)
答案 3 :(得分:3)
您的第一个程序只读取一个字符,将其打印出来然后退出。你的第二个程序有一个循环。它会一直读取一个字符并将其打印出来,直到它读取一个EOF字符。在任何给定时间只存储一个字符。
答案 4 :(得分:2)
您只使用变量c
一次包含一个字符。
使用t
显示第一个字符(putchar(c)
)后,您会通过将下一个字符(c
)分配给o
来忘记c
的值变量t
,替换之前的值({{1}})。
答案 5 :(得分:1)
代码在功能上等同于
main(){
int c;
c = getchar();
while(c != EOF) {
putchar(c);
c = getchar();
}
}
您可能会发现此版本更易于理解。将赋值放在条件中的唯一原因是避免必须两次输入'c = getchar()'。
答案 6 :(得分:0)
对于您更新的问题,在第一个示例中,只读取一个字符。它永远不会达到EOF。程序终止,因为在完成printf指令后没有任何操作可做。它只读一个字符。打印出来。放入换行符。然后终止,因为它没有更多的事要做。它不会读取多个字符。
然而,在第二个代码中,getchar和putchar存在于while循环中。在此,程序继续逐个读取字符(因为它是通过循环这样做),直到达到EOF字符(^ D)。此时,它匹配c!= EOF,并且由于条件不满足,因此它从循环中出来。现在没有更多的语句可以执行了。所以程序终止了。
希望这有帮助。