【问题标题】:(Exercise 1.6 K&R) How to verfiy that getchar() != EOF IS 0 OR 1?(练习 1.6 K&R)如何验证 getchar() != EOF 是 0 还是 1?
【发布时间】:2013-07-19 12:09:10
【问题描述】:

我刚刚开始自学编程 (C) 作为一种爱好。我正在使用 K&R。

 main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}

验证 getchar() != EOF 是否为 0 或 1

我想我明白发生了什么:

  1. c 被分配到键盘的下一个字符
  2. 检查c是否为EOF
  3. c 被分配 1 或 0,这取决于它是否为 EOF。
  4. 字符显示在输出中,或者如果 EOF 结束程序。

但是,我的解决方案是错误的,所以很明显我不明白:

main ()
{
    int c;

    while ((c = getchar()) != EOF)
        printf("%d\n", c);
}

这只是打印字符的值。如果我按回车键,还会打印“10”。

我以为它会打印 c。但是,它打印的是字符的值而不是 1 或 0 值。

我知道 c 在与 EOF 比较后被分配了 1 或 0。但我不确定我可以用什么逻辑来展示这一点。看来我需要以某种方式“摆脱”显示字符值,而是显示比较值。这是否意味着我需要退出 while 循环?如果是这样,我不知道如何(这只是一个猜测)。

如何简单地验证 c = 1 或 0?

还有,我怎么知道这个?我想我应该从中学到一些基本的东西。

main ()
{
    int c;

    while ((c = getchar()) != EOF != 0 != 1)
        putchar(c);
}

我也这样做了,我认为这似乎可行。因为它不输出任何字符,但我不确定这是否是他们正在寻找的解决方案......

【问题讨论】:

  • x != y 返回一个布尔值。您可以通过阅读 C 标准来验证它是否始终为 10(并假设您的编译器实际上遵循它,我想。)(尽管您在问另一个关于 c 的不相关问题,这是值由getchar 返回,而不是与 EOF 比较的值)。

标签: c eof getchar


【解决方案1】:

我知道 c 在与 EOF 比较后被赋值为 1 或 0

不,不是。看:

while ((c = getchar()) != EOF)

表达式为:(c = getchar()) != EOF,其中包含另一个表达式:(c = getchar()),它将键盘中的字符分配给cc等于 0 或 1! 这是表达式的结果。试试这个代码:

int main()
{
   char value;
   int c;
   value = ((c = getchar()) != EOF);
   printf("%i\n", value);
   return 0;
}

此代码将打印表达式(c = getchar()) != EOF 的值。其实你的代码可以这样写:

int main ()
{
    int c;
    char value = ((c = getchar()) != EOF);
    while (value)
    {
        printf("%d\n", c);
        value = ((c = getchar()) != EOF);
    }
    return 0;
}

表达式不再在while 中,其结果分配给value。上面的代码和你的代码将产生完全相同的输出。


编辑:

main ()
{
    int c;

    while ((c = getchar()) != EOF != 0 != 1)
        putchar(c);
}

上面的代码不是解决方案!这是重写的代码:

main ()
{
    int c;
    char value1;
    char value2;
    char value3;

    value1 = ((c = getchar()) != EOF);
    value2 = value1 != 0;
    value3 = value2 != 1;
    while (value3)
    {
        putchar(c);
        value1 = ((c = getchar()) != EOF);
        value2 = value1 != 0;
        value3 = value2 != 1;
    }
}

那么会发生什么? 假设getchar 将返回字符“A”。这意味着:

  • value1 将等于 1,因为“A”不同于 EOF
  • value2 将等于 1,因为 value1(等于 1)与 0 不同。
  • value3 将等于 0,因为 value2(等于 1)不同于 1:while(value3) 现在是 while(0),因此不会打印任何字符。

重要的是要了解,您可以将比较表达式的结果(即至少具有一个比较运算符的表达式)分配给变量,而这种表达式的结果是 0(表示 false)或 1(为真)。


关于 OP 评论的几句话:

嘿,谢谢。但是 K&R 明确表示“这具有将 c 设置为 1 或 0 的不良影响”。也许这就是我感到困惑的原因。

如果while 看起来像这样,c 将被分配为 0 或 1:

while (c = getchar() != EOF)

运算符!= 的优先级高于运算符=。这意味着将首先评估getchar() != EOF,然后将其结果分配给c

【讨论】:

  • 嘿,谢谢。但是 K&R 明确表示“这具有将 c 设置为 1 或 0 的不良影响”。也许这就是我感到困惑的原因。
  • 我开始觉得编程不适合我。即使是这些简单的概念,似乎也很难掌握。感谢您的解释!
  • @user2071506 啊来吧 :) 这完全正常!实际上,K&R 并不是为初学者设计的。这是最好的书之一,但它假设你已经有一些编程经验。 C 语言不是更容易学习编程的语言,但如果你知道它,你就可以无所不知;)
  • 注意:c 可以取 0 或 1 的值,因为许多键盘允许像 Ctrl-@ 或 Ctrl A 这样映射到 0 和 1 的输入。跨度>
【解决方案2】:

我意识到这个问题已经过时了,但选择的答案回答的不是问题的原意。 (这是从书中提出的一个不同的问题)我在这里澄清一些事情,并希望从谷歌搜索这个问题的其他人可以阅读我的答案,以便更好地理解来自 The C Programming Language 2nd 的问题 1-6版。

问题陈述验证 getchar() != EOF 是 0 还是 1

这本书暗示了

**c = (getchar() != EOF)**

等价于

**c = getchar() != EOF**

getchar() != EOF被测试时,

如果输入不是EOF,那么它应该是真的,因此返回一个True,或者在这个意义上是一个1

当然,如果输入EOF,那么getchar() != EOF 将返回False,或0

这就是为什么10 将被分配到c

对于书中提到的“不良影响”,因为10都不是原来的输入,这就意味着原来打算输出的字符丢失了,而这个是不可取的。

对于练习,使用这个:

#include <stdio.h>

main()
{
    int c;
    while ( c = getchar() != EOF ) {
        printf("%d\n", c);
    }
}

如果您输入的不是EOF,那么它将打印1

如果您的输入是EOF,则程序结束。

注意:要在 Windows 中键入 EOF,请使用 Ctrl + Z

编辑:

K&R 练习 1.6 的一个更简单的解决方案。

printf("%d", getchar() != EOF);

【讨论】:

    【解决方案3】:

    'c' 从 getchar 分配值,然后检查它是否为 EOF。

    如果没有赋值EOF,打印'c'的值;如果没有,则存在循环。

    EOF 的测试不会为 'c' 重新分配任何值,它只会成功或失败

    IOW,删除你的第 3 步。

    【讨论】:

      【解决方案4】:

      这里c没有赋值给比较结果。它包含value read form File.

      要检查比较结果,您需要如下所示

      int 结果 = ((c = getchar()) != EOF)

      然后使用结果来检查它是0还是1。

      printf("%d",result);
      

      【讨论】:

        【解决方案5】:

        我在这个问题上遇到了很多麻烦。

        如果我按回车键,也会打印“10”。

        另外,第 20 页 K&R 指出 '\n' 的 ASCII 值是 10。所以也许您无意中返回了该值?

        每次回到它,我都忘记了回车键IS NOT EOF。

        就像用户 Sayyora 上面指出的那样,您需要一个组合键来发出 EOF 信号。

        对于 Linux,它是:

        Ctrl + D

        另外,要杀死程序(至少在 X-Term 中),它是:

        Ctrl + C

        【讨论】:

          【解决方案6】:

          我在 DevC++ 4.9.9.2 中使用 C 源文件。我是 C 编程新手,我正在使用 K/R 2nd Ed。作为我的向导。在查看了上面的语句后,我发现以下几行提供了示例 1.6/1.7 所需的输出。随意纠正我的理解,但是通过了解作者关于使用括号和在 while 循环内外打印的提示,可以得到 1 或 0 的结果。最后一个 getchar() 是Dev-C 环境要求保持输入/输出屏幕打开以查看打印的语句。

          main()
          {
                int c; 
                while (c=getchar() !=EOF)
                      printf("%d",c);
                printf("%d",c);
                getchar();      
          

          【讨论】:

            【解决方案7】:
            // it will accept and print a single char, a word, a sentence...
            
            while (c != EOF) {
              printf("\ngetchar()) != EOF) = %d -- ", ((c=getchar()) != EOF));
              putchar(c);
            }
            
            //the trick is to only call getchar() once per char and EOF value
            //note: the last char is always char(10) which is invisible
            

            【讨论】:

            • 您正在为一个公认的新手程序员提供解决方案。理想情况下,这应该附有详细的解释。
            • 调用 getchar(c) 会消耗一个字符。那么如何打印每个 getchar(c) 并为同一个 getchar(c) 调用打印 EOF 值?一种方法是在 printf() 函数本身中调用 getchar(c)。这允许您在打印结果 char 和 EOF 时为输入的每个字符调用一次 getchar()。 while 语句中的子句允许这样做,但它不是很优雅。我不确定更高版本的 C 是否允许这样做,但 ANSI C 可以。要使用 ANSI 编译,请使用 -ansi 标志。
            • 刚刚意识到 getchar() 中的最后一个 char 是 char(10) 所以它是不可见的,但是 putchar(c) 像对待任何其他 char 一样对待它
            【解决方案8】:
            #include <stdio.h>
               
            int main(){
                int c;
                printf("Verifying that the expression 'c = getchar() != EOF' is: %d \n", (getchar() != EOF));
               
                return 0;
            }
            

            好吧,当您向“c”输入值时,它是 !=,因此它返回“1”,而当您发送 EOF 命令时,它返回“0”。

            在我看来,这是书中的练习,因为它是一开始它不应该更复杂。

            【讨论】:

              猜你喜欢
              • 2021-10-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-25
              • 1970-01-01
              • 1970-01-01
              • 2020-06-25
              • 1970-01-01
              相关资源
              最近更新 更多