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

我的问题很简单“为什么第10行和第11行的代码无法正常运行?” 我的代码的目的是完全按照原始的K&R代码进行操作,但不计算nc(getchar()==’\ n’)你能请教我吗?

略微修改的K&R代码:

/** K&R - 1.5.2 Character Counting **/ #include  /* count characters in input; 1st version */ main(){ long nc; nc = 0; while (getchar() != EOF){ if (getchar() != '\n'){ ++nc; } } printf("%ld\n", nc); } 

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

我目前的进步和理解:

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

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

 int c; while ((c = getchar()) != EOF) { if (c != '\n') ++nc; } 

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

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

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

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

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

 int c; [...] while ((c = getchar()) != EOF) { if (c != '\n') { ++nc; } } 

每次调用getchar()都会从stdin中消耗一个字符。