getchar()不传递EOF,Ctrl + Z不会终止Cygwin上的程序
这是一个简单的程序,计算字符串,符号和单词。
使用Cygwin进行计算一切正常。
但是在启动时,在输入值之后,程序不会打印nc
, nw
, nl
并等待输入更多值。
无论如何,将EOF
更改为13(回车)无济于事。
ctrl + Z也很有用:程序停止,写[n]+ Stopped
,其中’n’总是不同的数字。
代码是
#include #define IN 1 #define OUT 0 int main () { char c; int state; int nc, nw, nl; state = OUT; while ((c=getchar()) != EOF) { nc++; if (c == 'n') nw++; if (c == '\n' || c == ' ' || c == '\t') state = OUT; else if (state = OUT){ state = IN; nw++; } } printf ("%d %d %d", nc, nl, nw); }
getchar
返回int
,而不是char
。 它必须这样做,因为它可以返回一个字符值或返回特殊值EOF
来指示输入文件的结尾。 由于EOF
必须与char
类型的所有值不同,因此它不具有char
类型。 因此,您需要将包含其返回值的变量定义为int
,而不是char
。
在某些平台上, char
类型是有符号的,而getchar
函数实际上并不返回字符值,而是将字符值包装为非负值。 实际上,这意味着ASCII字符不变,但在某些平台上,非ASCII字符转换为128到255之间的值,而不是-128和-1之间的值。 因此,一般来说,当您将getchar
的返回值用作char
时,需要将其转换为char
。 在char
类型未签名的平台上,这不会改变任何内容,但在签名char
类型的平台上,必须避免将字符255误认为是文件的末尾。
int c; … while ((c = getchar()) != EOF) { … if (c == 'n') /* ok because 'n' is part of ASCII and thus always positive */ … if ((char)c == some_other_char) /*cast needed in general*/ … }
在Cygwin中,与其他类Unix系统一样,在行的开头按Ctrl + D表示输入结束。 在Windows下,您需要按Ctrl + Z (在Cygwin下,再次像在其他类Unix系统中一样,它会暂停程序:它已停止,但可以使用命令bg
恢复)。 这些都没有向程序发送控制字符,它们发送文件结束指示,C的getchar
实现转换为EOF
值。
初始化用于计数的变量:
int nc = 0, nw = 0, nl = 0;
当你不这样做时,他们得到随机值。
另外,你计算单词的逻辑是错误的。
else if (state = OUT)
你可能意味着else if (state == OUT)
。
#include #define IN 1 #define OUT 0 int main() { int c, nl, nw, nc, state; //c is an int not a char state = OUT; nl = nw = nc = 0; // initialize variables to 0 while ((c = getchar()) != EOF) { ++nc; if (c == '\n') // if c is a newline character ++nl; //increment no of lines if (c == ' ' || c == '\n' || c == '\t') state = OUT; else if (state == OUT) // == for comparing { state = IN; ++nw; } } printf("%d %d %d\n", nl, nw, nc); return 0; }
你的程序看起来应该像上面那样。 c
是一个int
而不是char
因为getchar
将输入转换为unsigned char
,因为它不能保持负值,并且因为EOF
保持-1,所以while
循环永远不会结束。
当你按下CTRL + Z(在Windows中按CTRL + D)时结束,因为按下它将模拟stdin
的EOF
。
你这里有几个bug。
int nc, nw, nl;
应该
int nc = 0, nw = 0, nl = 0; else if (state = OUT){
我想你的意思
else if (state == OUT) {
ENTER是10而不是13。
cygwin上的getchar()在文件末尾返回-1(我不知道为什么)。 所以你可以用-1代替EOF。 您可以通过以下方式测试程序:./ program.exe
还有这个问题吗? 可能已找到一个解决方案:如果你键入一些字符然后按ctrl-z,那么ctrl-z算作普通字符(代码26),但是在一行的开头(意思是:除了ctrl-z char)它算作EOF。 所以:
while ( (ch=getchar())!=26 ){ if (ch==EOF) break; }
这样,无论你在哪里键入ctrl-z char,迭代都会结束。