C编程 - K&R示例1.5.2 - 修改后的程序无法按预期运行

pyi*_*pan 2 c increment kernighan-and-ritchie getchar

我的问题只是"为什么第10行和第11行的代码无法正常运行?" 我的代码的目的是完全按照原始的K&R代码进行操作,但不计算nc(getchar()=='\n'),请你启发我吗?

略微修改的K&R代码:

/** K&R - 1.5.2 Character Counting **/
#include <stdio.h>

/* count characters in input; 1st version */
main(){
  long nc;

  nc = 0;
  while (getchar() != EOF){
    if (getchar() != '\n'){
      ++nc;
    }
  }
  printf("%ld\n", nc);
}
Run Code Online (Sandbox Code Playgroud)

我使用的是64位Windows 7,CodeBlocks10.05,GNU GCC编译器.

我目前的进步和理解:

在示例运行中,我输入单词two并按Enter键,等于4个输入,然后按ctrl + Z输入一个^Z或EOF字符.程序然后打印1.我期待它打印3.我想唯一合乎逻辑的解释是它完全与我的意图完全相反(它只计算换行符?).事实证明,如果我输入单词two并按回车键,可以说4次,它会打印出来4.它似乎在计算nc输入的每个换行符,但是如果我单独输入(在这种情况下为4次)然后按EOF,它总是打印出来0.经过进一步的实验,通过一些看不见的手4可能是这个程序的神奇数字.如果我启动它并完全按下输入键(一个可被4整除的数字)然后打印出EOF 0.但是,如果我输入其他次数输入EOF什么都不做,我必须^Z一个接一个地输入两行,以正确结束while循环,然后打印1.这令人难以置信!

Jon*_*ler 6

麻烦的是你需要保存getchar()- 中的值int- 因为你每次增加计数时都要读两个字符.其中一个是在EOF测试中; 第二个是换行测试.

int c;

while ((c = getchar()) != EOF)
{
    if (c != '\n')
        ++nc;
}
Run Code Online (Sandbox Code Playgroud)

您需要将结果存储getchar()在a int而不是a中的原因char是它可以返回每个可能的char值以及不同的值EOF.如果您不使用int(直接存储到a中char),将会发生以下两种情况之一:

  1. 如果char是签名类型,合法字符(通常是y-umlaut,ÿ,带有DIAERESIS的LATIN SMALL LETTER Y,U + 00FF - 至少在源自Latin 1或ISO 8859-1的代码集中)将被解释为等效于EOF,并且您的程序将提前终止.
  2. 如果char是无符号类型,则任何字符都不等同于EOF,因此程序将永远不会停止循环.

这些情况都不可取.存储的返回值getchar()int防止这两个问题; 这是"唯一的"(或者,至少是最简单的)正确的方法.


sit*_*sys 5

简单地说,你正在调用getchar()两次,所以你在每次迭代中消耗两个字符.

您应该了解调用getchar()从输入流中读取字符.如果要测试换行符,则应将该字符存储在变量中,然后测试该变量.