我对 K&R 中提到使用 getchar()
的程序感到困惑。它输出的结果与输入字符串相同:
#include <stdio.h>
main(){
int c;
c = getchar();
while(c != EOF){
putchar(c);
c = getchar();
}
}
为什么它打印整个字符串?我本以为它会读取一个字符并再次要求输入。另外,我们输入的所有字符串是否都以EOF结尾?
我对 K&R 中提到使用 getchar()
的程序感到困惑。它输出的结果与输入字符串相同:
#include <stdio.h>
main(){
int c;
c = getchar();
while(c != EOF){
putchar(c);
c = getchar();
}
}
为什么它打印整个字符串?我本以为它会读取一个字符并再次要求输入。在你可能使用的简单设置中,getchar
与缓冲输入一起工作,所以你必须在 getchar
获得任何内容之前按回车键。字符串不是由 EOF
终止的;事实上,EOF
不是一个字符,而是表示文件结束的魔术值。但是 EOF
不是读取的字符串的一部分。当没有剩余内容可以读取时,它是 getchar
返回的值。
get char()
会像“abc”一样获取我的输入,但在计数时,它将是4
而不是3
。 因此,我使用gdb
进行调试,结果发现附加的一个'字符'是(nl),其ascii码为0x0a。那么,我的输入是字符串吗?难道字符串不是以'\0'结尾的吗?为什么会有(nl)呢? - ray6080getchar()
和相关函数从一个底层的缓冲区/流中读取数据。当你输入文本时,文本将存储在某个缓冲区中,getchar()
可以逐个字符地读取它。每次读取都返回下一个字符,直到达到缓冲区的末尾。它不询问后续字符的原因是它可以从缓冲区获取下一个字符。
如果您运行脚本并直接在其中输入,它将继续提示您输入,直到您按下CTRL+D(文件结束)。如果您像这样调用它:./program < myInput
,其中myInput
是带有一些数据的文本文件,当getchar()
读取到输入的末尾时,它会获取EOF
。 EOF
不是存在于流中的字符,而是一个哨兵值,表示已到达输入的结尾。
额外注意,如果getchar()
遇到错误,它也将返回EOF
,因此您应该检查ferror()
。以下是示例(未经过测试,但您可以理解思路)。
main() {
int c;
do {
c = getchar();
if (c == EOF && ferror()) {
perror("getchar");
}
else {
putchar(c);
}
}
while(c != EOF);
}
按照 C
定义,字符串以 '\0'
结尾。程序中不存在 "C 字符串"
。
你的程序从标准输入(键盘)读取字符(缓冲直到按下 ENTER 键),并将它们写回标准输出(屏幕)。不管你输入多少字符或者持续多长时间,它都会这样做。
要停止程序,你需要表明标准输入没有更多数据 (啥?键盘怎么可能没有更多数据呢?)。
你只需按下 Ctrl+D(Unix)或 Ctrl+Z(Windows)模拟文件已经到达结尾。
在 C
语言中,Ctrl+D(或 Ctrl+Z)并不是真正的字符。
如果你使用输入重定向运行程序,则 EOF
是实际的文件结尾,而不是虚构的结尾
./a.out < source.c
getchar()
函数读取一个输入字符并将该字符作为函数的值返回。如果读取字符时出现错误或到达了输入的结尾,getchar()
将返回一个特殊的值,用 EOF
表示。
getchar()
的定义,它从标准输入中读取一个字符。不幸的是,stdin
被误认为是键盘,这可能并非getchar
的情况。getchar
使用缓冲区作为stdin
,逐个读取单个字符。在您的情况下,由于没有EOF
,getchar
和putchar
会运行多次,并且看起来整个字符串一次性打印出来。做一个小改变,您就会明白:putchar(c);
printf("\n");
c = getchar();
现在看一下输出结果与原始代码的比较。
另一个例子可以帮助您理解getchar
和缓冲的stdin
的概念:
void main(){
int c;
printf("Enter character");
c = getchar();
putchar();
c = getchar();
putchar();
}
getchar
运行时,第二次输入时你输入了任何字符吗?没有,但是 putchar
仍然可以工作。getchar
将此缓冲区用作 stdin
。