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

时间:2012-08-24 21:25:45

标签: c increment getchar kernighan-and-ritchie

我的问题很简单“为什么第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);
}

我使用的是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。这令人难以置信!

3 个答案:

答案 0 :(得分:6)

问题是您需要将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,因此程序永远不会停止循环。
  3. 这两种情况都不可取。将getchar()的返回值存储在int可以防止这两个问题;它是“唯一的”(或者,至少是最简单的)正确的方法。

答案 1 :(得分:5)

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

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

答案 2 :(得分:3)

int c;

[...]

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

每次拨打getchar()时,您都会使用stdin中的角色。