【问题标题】:`getchar()` gives the same output as the input string`getchar()` 给出与输入字符串相同的输出
【发布时间】:2011-04-10 06:14:27
【问题描述】:

我对 K&R 中提到的使用 getchar() 的程序感到困惑。它给出与输入字符串相同的输出:

#include <stdio.h>

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

为什么要打印整个字符串?我希望它能够读取一个字符并再次询问输入。

而且,我们输入的所有字符串都以 EOF 结尾吗?

【问题讨论】:

  • EOF 不是 char 值而不是 int 吗?
  • 我认为它是一个值为-1的int。
  • 字符串由 \0 终止。文件由 EOF 终止,即 -1
  • 我打开了一个文本文件,但在它的末尾没有看到 EOF。 :) 无论如何,如果他们愿意的话,可以提出一个 EOF 为 -42 的 C 实现......不管 EOF 定义为什么值都无关紧要。您应该始终使用常量。
  • @Fahad:文件在其末尾自然终止,而不是在文件中的特定位置存在特定值。 EOF 的值是实现所需的任何值(通常为 -1;但总是 EOF

标签: c eof getchar


【解决方案1】:

在您可能使用的简单设置中,getchar缓冲 输入一起使用,因此您必须在 getchar 读取任何内容之前按 Enter。字符串不以EOF 结尾;事实上,EOF 并不是一个真正的字符,而是一个表示文件结束的魔法值。但是EOF 不是读取的字符串的一部分。这是getchar 在没有内容可读时返回的内容。

【讨论】:

  • 当我在 K&R 中尝试 count char 程序时,我发现get char() 得到我的输入就像“abc”,在计数时,它会是4 而不是3,所以我使用了gdb 调试一下,发现多了一个‘字符’是(nl),它的ascii 码是0x0a。那么,我的输入是字符串吗?那个字符串不是被'\0'终止的吗?为什么会有 (nl)?
  • 那是因为终止该行的换行符是输入的一部分。 C就是这样,处理吧。
【解决方案2】:

getchar() 和朋友从中读取一个底层缓冲区/流。当您输入文本时,文本会存储在某处的缓冲区中。 getchar() 可以一次流过一个字符。每次读取都返回下一个字符,直到它到达缓冲区的末尾。它不要求您输入后续字符的原因是它可以从缓冲区中获取下一个字符。

如果您运行脚本并直接在其中输入,它将继续提示您输入,直到您按下 CTRL+D(文件结尾)。如果您将其称为./program &lt; myInput,其中myInput 是一个包含一些数据的文本文件,那么当它到达输入末尾时,它将获得EOFEOF 不是流中存在的字符,而是指示何时到达输入末尾的标记值。

作为一个额外的警告,我相信getchar() 在遇到错误时也会返回EOF,因此您需要检查ferror()。下面的示例(未经测试,但您明白了)。

main() {
    int c;
    do {
        c = getchar();
        if (c == EOF && ferror()) {
            perror("getchar");
        }
        else {
            putchar(c);
        }
    }
    while(c != EOF);
}

【讨论】:

  • 感谢您提供 CTRL+D 信息。
  • 'bash' 创建缓冲区还是 Linux 呢? K&R 没有提到这个问题似乎很奇怪,特别是因为它们是基于 Unix 的。谢谢。
【解决方案3】:

字符串,由C 定义,由'\0' 终止。您的程序中没有"C strings"

您的程序从标准输入(键盘)读取字符(缓冲到 ENTER)并将它们写回标准输出(屏幕)。无论您输入多少字符或输入多长时间,它都会执行此操作。

要停止程序,您必须指出标准输入没有更多数据(嗯??键盘怎么可能没有更多数据?)

您只需按 Ctrl+D (Unix) 或 Ctrl+Z (Windows) 即可假装文件已结束。
Ctrl+D(或 Ctrl+Z)不是真正的字符在 C 这个词的意义上。

如果您使用输入重定向运行您的程序,EOF 是文件的实际结尾,而不是让人相信的
./a.out &lt; source.c p>

【讨论】:

    【解决方案4】:

    getchar() 读取输入的单个字符并将该字符作为函数的值返回。如果读取字符出错,或者到达输入结尾,getchar() 将返回一个特殊值,由EOF 表示。

    【讨论】:

      【解决方案5】:

      根据getchar()的定义,它从标准输入中读取一个字符。不幸的是,stdin 被误认为是键盘,getchar 可能不是这种情况。 getchar 使用缓冲区作为stdin 并一次读取一个字符。在您的情况下,由于没有EOFgetcharputchar 正在运行多次,它看起来像整个字符串一次打印出来。稍作改动,你就会明白:

      putchar(c);
      printf("\n");     
      c = getchar();
      

      现在看看输出与原始代码的对比。

      另一个例子将解释getchar 和缓冲stdin 的概念:

      void main(){
      int c;
      printf("Enter character");
      c = getchar();
      putchar();
      c = getchar();
      putchar();
      }
      

      在第一种情况下输入两个字符。 getchar 第二次运行时,你输入了任何字符吗?否,但 putchar 仍然有效。

      这最终意味着有一个缓冲区,当您输入某些内容并单击 Enter 时,它就会进入缓冲区。 getchar 将此缓冲区用作stdin

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-30
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-02
        相关资源
        最近更新 更多