getchar()不传递EOF,Ctrl + Z不会终止Cygwin上的程序

这是一个简单的程序,计算字符串,符号和单词。

使用Cygwin进行计算一切正常。

但是在启动时,在输入值之后,程序不会打印ncnwnl并等待输入更多值。

无论如何,将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)时结束,因为按下它将模拟stdinEOF

你这里有几个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,迭代都会结束。