当我运行以下代码并输入一个句子时,我没有得到任何输出。光标只是转到一个新行。
我直接从书中复制了这本书,然后仔细检查了它是否有错误(kernighan& ritchie的第1版C编程语言)
#include <stdio.h>
int main()
{
int c,i,nwhite,nother;
int ndigit[10];
nwhite=nother=0;
for(i=0;i<10;++i)
ndigit[i] = 0;
while (( c=getchar()) != EOF)
if(c>= '0' && c<= '9')
++ndigit[c-'0'];
else if (c==' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;
printf("digits =");
for( i=0; i<10; ++i)
printf("%d",ndigit[i]);
printf(", white space = %d, other = %d\n", nwhite,nother);
return 0;
}
答案 0 :(得分:0)
由于您正在测试从其他来源复制的程序,我认为您不想更改它,而是要了解它。
getchar()
从标准输入中获得正好1个字符,这是标准标题stdin
中名为<stdio.h>
的文件。
标准输入stdin
被视为文件
从形式上讲,文件结尾是“标记”而不是“字符”
但是,通常,使用特定的“字符”来标记文本文件的“文件结尾”
在Windows中,“文件结束”标记是字符CTRL-Z(其ASCII码为26)
在Linxu中,标记是CTRL-D(其ASCII码为4)。
另一方面,标准输入通常具有以下行为:
如果用户未按Enter键,则标准输入不会将控制权返回给程序。即使您输入“文件结束”字符(例如,CTRL-Z),也会发生这种情况 但是,其他行为也是可能的 例如,在Ubuntu控制台中,我获得了CTRL-D被识别而无需等待按下Enter键。
无论如何,您必须明确地在系统控制台中键入文件结尾标记。
因此,必须为自己按下CTRL-Z(可能后跟Enter)或CTRL-D。
关于ENTER和EOF
按Enter键后,您的程序将测试EOF
,即系统中的“文件结束”标记。
但是,Enter关键字不会打印“文件结束”标记,而只会打印“行尾”标记,这与标准字符换行符'\n'
相对应。
因此,如果希望在按Intro / Enter后while()
循环终止,则必须对'\n'
进行测试,而不是EOF
。
观察
可以观察到getchar()
不检索字符CTRL-Z,因为CTRL-Z的ASCII代码是26,但是getchar()
检索负值(通常{{1} }})。
这意味着-1
将字符ASCII 26识别为文件结束标记,然后将其转换为C中含义的值,由宏getchar()
提供,而不是26。 / p>
我的意思是EOF
不是CTRL-Z,然后在假设ASCII 26(CTRL-Z)将被发送到文本文件的情况下,不能天真地发送EOF
。
总结一下,我认为重新阐明“文件结束”的抽象概念,EOF
的作用以及“标记”和“字符”之间的区别是很重要的。 />
(另一个例子:在Windows中,“行尾”的“标记”是一对字符CTRL-M CTRL-J,它不仅是1个字符,而是2)。
引自标准:
getchar函数返回指向的输入流中的下一个字符 标准输入。如果流位于文件结尾,则设置流的文件结束指示符 getchar返回EOF。如果发生读取错误,则设置流的错误指示符 getchar返回EOF。