【问题标题】:K&R book 1.5.1 File CopyingK&R book 1.5.1 文件复制
【发布时间】:2016-04-18 18:59:13
【问题描述】:

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

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

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

代码是:

#include <stdio.h>

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

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

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

显然对我来说还有很大的差距。

感谢您的帮助

【问题讨论】:

  • 不要使用 K&R 编码风格,它已被弃用。 C 在过去 > 17 年中不断发展。关于您的文字:不确定您的具体问题是什么。这不是一个教程网站。
  • 那是因为标准输入和输出被缓冲了:你输入的字符被存储在内部,直到你按下回车,然后被批量处理。同样,输出字符将被存储,直到您打印一个换行符,此时所有内容都被刷新。如果你想要输入和输出之间直接对应,你必须使用特殊的库而不是控制台 I/O。
  • CR(又名回车)不会终止流。
  • @Olaf 第一个版本教的是旧的、准标准的 C,这是正确的。应该避免。第二个版本教授 ANSI-C,这仍然非常相关。大量的 C 仍然是用 ANSI-C 编写的。
  • Suffering From Buffering 可能会有所帮助。

标签: c getchar putchar


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

    感谢您的回答,您描述的缓冲非常有用且有趣。

    显然,我也一定有误读/理解,K&R。他们将文本流定义为“......由零个或多个字符组成,后跟一个换行符”,我认为这意味着返回/输入键;结束它,然后允许输出。

    另外,我要感谢所有提供帮助的 cmets 的人。

    顺便说一下,我清楚地知道我必须输入^D才能生成EOF,从而终止程序。感谢你们都是顶级程序员,感谢你们的时间。我想我需要找到另一个地方来讨论 R&R 写的关于这个练习的文本是关于什么的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-12
      • 2016-12-04
      • 1970-01-01
      • 2020-04-05
      • 2011-01-23
      • 2013-11-22
      相关资源
      最近更新 更多