【问题标题】:C programming - K&R example 1.5.2 - modified program not functioning as intendedC 编程 - K&R 示例 1.5.2 - 修改后的程序未按预期运行
【发布时间】:2012-08-20 11:00:14
【问题描述】:

我的问题很简单:“为什么我在第 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。我想唯一合乎逻辑的解释是它的行为与我的意图完全相反(它 only 计算换行符?)。事实证明,如果我输入单词two 并按回车键,比如说4 次,它会打印出4。对于输入的每个换行符,它似乎都在计算nc,但是如果我单独按回车(在本例中为 4 次)然后按 EOF,它总是打印0。经过进一步的实验,在某些人看来,看不见的 4 可能是这个程序的一个神奇数字。如果我启动它并准确地按回车键(一个可被 4 整除的数字)然后 EOF 打印0。但是,如果我按其他次数输入,EOF 什么也不做,我必须输入^Z 两行,一个接一个,才能正确结束while 循环,并打印1。这让我大吃一惊!

【问题讨论】:

    标签: c increment getchar kernighan-and-ritchie


    【解决方案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、ÿ、带分音符号的拉丁小写字母 Y、U+00FF — 至少在源自拉丁语 1 或 ISO 8859-1 的代码集中)将是解释为等效于 EOF,并且您的程序将提前终止。
    2. 如果 char 是无符号类型,则任何字符都不会等同于 EOF,因此程序永远不会停止循环。

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

    【讨论】:

      【解决方案2】:

      简单地说,您调用了两次getchar(),因此您在每次迭代中消耗了两个字符。

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

      【讨论】:

        【解决方案3】:
        int c;
        
        [...]
        
        while ((c = getchar()) != EOF) {
            if (c != '\n') {
              ++nc;
            }
        }
        

        每次您调用getchar() 时,您都会消耗来自stdin 的字符。

        【讨论】:

        • 你应该解释一下为什么你的解决方案是正确的,只是一点点。
        • 哇,我刚刚写完了,除了我把 c 变成了一个 char 变量,它和原来的 K&R 代码做同样的事情吗?
        • @pyingSaucepan char 的宽度不足以容纳EOF,这正是getchar 返回int 的原因。
        • 当我输入“二”并按回车和EOF时,它仍然返回4
        • 抱歉,我忘了在 c = getchar() 周围加上括号
        猜你喜欢
        • 2022-12-10
        • 1970-01-01
        • 1970-01-01
        • 2020-01-14
        • 2020-05-24
        • 1970-01-01
        • 2020-01-29
        • 2020-11-23
        • 1970-01-01
        相关资源
        最近更新 更多