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
),则会发生以下两种情况之一:
- 如果
char
是带符号的类型,则合法字符(通常为y-umlaut,ÿ,LATIN SMALL LETTER Y WITH DIAERESIS,U + 00FF – 至少在源自Latin 1或ISO 8859-1的代码集中)将被解释为等效于EOF ,你的程序将提前终止。 - 如果
char
是无符号类型,则任何字符都不等同于EOF,因此程序将永远不会停止循环。
这些情况都不可取。 将getchar()
的返回值存储在int
可以防止这两个问题; 它是“唯一的”(或者,至少是最简单的)正确的方法。
简单地说,你调用getchar()
两次,所以你在每次迭代中消耗两个字符。
您应该了解调用getchar()
从输入流中读取一个字符。 如果要测试换行符,则应将该字符存储在变量中,然后测试该变量。
int c; [...] while ((c = getchar()) != EOF) { if (c != '\n') { ++nc; } }
每次调用getchar()
都会从stdin
中消耗一个字符。