我已经开始阅读“ C编程语言” (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 时退出,而第二个程序打印整个字符串然后等待更多用户输入。为什么它等待另一个字符串并且不像第一个字符串那样退出?

有帮助吗?

解决方案

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

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


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

其他提示

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

在第二个例子中, getchar 函数位于循环中,一直持续到遇到 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键。如果你发表评论,也要这样做 if(c!='\ n')也许您可以确定您的输入,输出或两者是否以某种方式缓冲。 如果你运行上面这样会变得更有趣: ./mytest | ./mytest

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

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

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

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

代码在功能上等同于

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

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

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

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

希望这有帮助。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top