c - K&R book 1.5.1 文件复制

标签 c getchar putchar

我浏览了有关此 K&R 示例的网站,答案似乎围绕“为什么这是 int 类型或什么是 EOF?”有点家伙。我相信我理解这些。 这是我不明白的结果。我原以为这段代码会获取一个字符,打印它,然后等待另一个字符或 EOF。

我看到的结果是输入等待,直到我按回车键,然后我输入的所有内容都会显示出来,并且等待输入的内容越来越多。

while 循环是否只是“循环”,直到我用回车符结束文本流,然后显示 putchar(c) 隐藏在某处的内容?

代码是:

#include <stdio.h>

/* copy input to output: 1st version */
main()
{
    int c;

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

现在,如果我在 while 之前偷偷地在线路上添加 putchar(c) ,我就得到了我所期望的结果。我仍然必须输入文本流并按回车键。结果是流的第一个字符,程序退出。

显然,我的情况存在很大的差距。

感谢您的帮助

最佳答案

默认情况下,stdin 和 stdout 是缓冲的。这意味着他们会保存批量字符并立即发送它们以提高效率。通常,批处理会被保存,直到缓冲区中没有更多空间或流中出现换行符或 EOF。

当您调用 getchar() 时,您正在向来自标准输入的字符进行询问。假设您输入 A,该字符将保存在缓冲区中,然后系统等待更多输入。如果您输入 B,该字符接下来会进入缓冲区。也许在那之后,你按下 Enter 键,一个换行符就会被放入缓冲区中。但换行符也会中断缓冲过程,因此对 getchar() 的原始调用返回缓冲区中的第一个字符 (A)。在下一次迭代中,您再次调用 getchar(),它会立即返回缓冲区中的下一个字符 (B)。等等。

所以这并不是说你的 while 循环一直运行到你结束该行,而是第一次调用 getchar() (当缓冲区为空时)正在等待,直到它有一个完整的缓冲区或者它看到了换行符。

当您交错输出函数(例如 putchar())时,大多数 C 运行时库将在您执行将数据发送到 stdout 的操作时“刷新”stdin(反之亦然)。 (目的是确保用户在程序等待输入之前看到提示。)这就是为什么在添加 putchar() 调用时开始看到不同行为的原因。

您可以使用flush()函数手动刷新缓冲区。您还可以使用 setvbuf() 控制标准流使用的缓冲区大小。

正如 Han Passant 在评论中指出的那样,换行符不会“终止流”。要在 stdin 上获取 EOF,您必须键入 Ctrl+D(或者在某些系统上键入 Ctrl+Z)。 EOF 也会刷新缓冲区。如果您将文件或另一个程序的输出重定向到 stdin,则一旦输入耗尽,就会发生 EOF。

虽然 K&R C 确实很古老,甚至 ANSI C 现在也不像以前那么常见了,但有关使用 stdin 和 stdout 进行缓冲的所有内容在当前标准甚至 C++ 中实际上都是相同的。我认为唯一显着的变化是 C 标准现在明确指出需要让 stdin 和 stdout 导致另一个刷新。

关于c - K&R book 1.5.1 文件复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36702202/

相关文章:

c - 为什么这不消除 C 中的双空格?这是 K & R 中的 getchar() 练习之一

c - c中的十六进制到ASCII

c - 线程不并行运行

c - 将整个输入保存在整数数组中(使用 getchar 读取)

c - 从 c 中的键盘获取字符时出现多字符警告

c - 打印 EOF 的值

c++ - 循环中的预递增/递减与使用 gcc 和 Visual C 的递增/递减

C 程序(编译为 fcgi)给出 500 内部错误

c - C 中的 for 循环和 getchar()

c - 如何阅读直到换行