'getchar()' 给出与输入字符串相同的输出

`getchar()` gives the same output as the input string

提问人:Shubham 提问时间:9/9/2010 最后编辑:NANDShubham 更新时间:6/16/2020 访问量:105587

问:

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

#include <stdio.h>

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

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

而且,我们输入的所有字符串是否都由 EOF 终止?

c eof getchar

评论

0赞 9/9/2010
EOF 不是 char 值而不是 int 吗?
6赞 Shubham 9/9/2010
我认为它是一个值为 -1 的 int。
2赞 9/9/2010
字符串由 \0 终止。文件由 EOF 终止,EOF 为 -1
3赞 Timothy 9/9/2010
我打开了一个文本文件,但末尾没有看到 EOF。:)无论如何,如果他们愿意,可以想出一个 C 的实现,其中 EOF 为 -42......根据值将 EOF 定义为什么并不重要。应始终使用常量。
8赞 pmg 9/9/2010
@Fahad:文件在其末尾自然终止,而不是由于文件中特定位置存在特定值而终止。EOF 的值是实现想要的任何值(通常为 -1;但始终是 EOF)

答:

42赞 Erich Kitzmueller 9/9/2010 #1

在您可能使用的简单设置中,使用缓冲输入,因此您必须在 getchar 读取任何内容之前按 Enter。字符串的结尾不是 ;其实,并不是真正的字符,而是一个表示文件结尾的魔术值。但不是读取的字符串的一部分。当没有什么可读的时候,它就会返回。getcharEOFEOFEOFgetchar

评论

2赞 ray6080 8/26/2014
当我在 K&R 中尝试 count char 程序时,我发现我的输入像“abc”一样,计数时,它会代替 ,所以我曾经调试过它,结果发现额外的一个“字符”是 (nl),其 ascii 代码是 0x0a。那么,我的输入是字符串吗?那个字符串不是以“\0”结尾吗?为什么有(nl)?get char()43gdb
1赞 Erich Kitzmueller 8/26/2014
这是因为终止行的换行字符是输入的一部分。C就是这样,处理它。
3赞 Petros 9/9/2010 #2

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

32赞 Timothy 9/9/2010 #3

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

如果您运行脚本并直接在其中键入内容,它将继续提示您输入,直到您按 +(文件末尾)。如果你像 where 一样调用它,就像一个包含一些数据的文本文件,它将在到达输入末尾时获得。 不是存在于流中的字符,而是一个 sentinel 值,用于指示何时到达输入的末尾。CTRLD./program < myInputmyInputEOFEOF

作为额外的警告,我相信如果遇到错误也会返回,因此您需要检查.下面的示例(未经过测试,但您明白了)。getchar()EOFferror()

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

评论

3赞 estrar 1/29/2014
感谢您提供 CTRL+D 信息。
1赞 Ron 7/21/2016
是“bash”创建缓冲区还是 Linux 创建?K&R 没有提到这个问题似乎很奇怪,特别是因为它们是基于 Unix 的。谢谢。
11赞 pmg 9/9/2010 #4

根据定义,字符串的结尾是 。你的程序中没有。C'\0'"C strings"

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

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

您只需按 + (Unix) 或 + (Windows) 即可假装文件已到达末尾。
+(或+)并不是真正意义上的字符。
CtrlDCtrlZCtrlDCtrlZC

如果使用输入重定向运行程序,则 EOF 是文件的实际结尾,而不是 source.c < make belief one
./a.out

2赞 Revanth Kumar 1/14/2015 #5

根据 的定义,它从标准输入中读取一个字符。不幸的是,它被误认为是键盘,而 . 使用缓冲区作为,一次读取一个字符。在你的例子中,因为没有 ,和 正在运行多次,并且在你看来,整个字符串一次被打印出来。做一个小小的改变,你就会明白:getchar()stdingetchargetcharstdinEOFgetcharputchar

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

现在看一下输出与原始代码的比较。

另一个例子将向您解释 和 缓冲的概念:getcharstdin

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

在第一种情况下输入两个字符。第二次跑步时,你输入任何字符吗?否,但仍然有效。getcharputchar

这最终意味着有一个缓冲区,当您输入某些内容并单击回车时,它就会进入缓冲区并稳定下来。 将此缓冲区用作 。getcharstdin