【问题标题】:K&R 1.5.4 word counting in CK&R 1.5.4 C 中的字数统计
【发布时间】:2012-05-10 03:56:25
【问题描述】:

我是一名初出茅庐的 C 程序员,我编写了这个程序来计算第 2 版 K&R 1.5.4 的字数。我的 if 语句有问题吗?代码似乎在不应该增加变量时增加了变量,因为它不符合初始测试。

#include <stdio.h>
#define IN 1
#define OUT 0


main()
{
      int word, state, c;

      word = state = OUT;

      while((c = getchar()) != EOF)
      {
               if(c != ' ' || c != '\n' || c != '\t')
               {
                    if(state == OUT)
                    {
                             word++;
                             state = IN;
                    }

                    /*else
                    {
                         state = IN;
                    }*/
               }

               if(c == ' ' || c == '\n' || c == '\t')
               {
                   state = OUT;
               }

               printf("char: %c %x | state: %d | word: %d\n", c, c, state, word); 
      }

      printf("\n//maniac: %d\n", word);

这会导致:

>count_word_my.exe
Hello  he   he
char: H 48 | state: 1 | word: 1
char: e 65 | state: 1 | word: 1
char: l 6c | state: 1 | word: 1
char: l 6c | state: 1 | word: 1
char: o 6f | state: 1 | word: 1
char:   20 | state: 0 | word: 1
char:   20 | state: 0 | word: 2
char: h 68 | state: 1 | word: 3
char: e 65 | state: 1 | word: 3
char:   20 | state: 0 | word: 3
char:   20 | state: 0 | word: 4
char:   20 | state: 0 | word: 5
char: h 68 | state: 1 | word: 6
char: e 65 | state: 1 | word: 6
char:
 a | state: 0 | word: 6

char:
 a | state: 0 | word: 7

//maniac: 7

我修改的K&R代码:

#include <stdio.h>

#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */

/* count lines, words, and characters in input */
main()
{
      int c, nl, nw, nc, state;

      state = OUT;
      nl = nw = nc = 0;
      while ((c = getchar()) != EOF) {
            ++nc;
            if (c == '\n')
               ++nl;
            if (c == ' ' || c == '\n' || c == '\t')
               state = OUT;
            else if (state == OUT) {
                 state = IN;
                 ++nw;
            }
            printf("char: %c %x | state: %d | word: %d\n", c, c, state, nw);
      }
      printf("%d %d %d\n", nl, nw, nc);
}

K&R 代码导致:

>count_word_test.exe
Hello  he   he
char: H 48 | state: 1 | word: 1
char: e 65 | state: 1 | word: 1
char: l 6c | state: 1 | word: 1
char: l 6c | state: 1 | word: 1
char: o 6f | state: 1 | word: 1
char:   20 | state: 0 | word: 1
char:   20 | state: 0 | word: 1
char: h 68 | state: 1 | word: 2
char: e 65 | state: 1 | word: 2
char:   20 | state: 0 | word: 2
char:   20 | state: 0 | word: 2
char:   20 | state: 0 | word: 2
char: h 68 | state: 1 | word: 3
char: e 65 | state: 1 | word: 3
char:
 a | state: 0 | word: 3

char:
 a | state: 0 | word: 3
2 3 16
^C

当我的代码不满足第一个 if 语句中的测试时,它如何在处理“Hello”之后的第二个空格 (0x20) 时递增 word/nw?即使它确实到达了第二个 if 语句,我也会假设它将“状态”变量设置为 1(IN)。我在这里遗漏了一些重要的东西。我非常感谢提供的任何帮助。谢谢。

【问题讨论】:

    标签: c if-statement word-count


    【解决方案1】:

    好吧,每个char 都会将此评估为真if(c != ' ' || c != '\n' || c != '\t'),因为没有字符同时是' ''\n''\t'

    应该是这样的:

    if(c != ' ' && c != '\n' && c != '\t')
    

    【讨论】:

    • 是的,除非你使用 C++ 并且做一些邪恶的操作符重载(muhahaha)。
    • 谢谢宾亚敏。我应该进一步评估代码中的逻辑,而不是仅仅做出错误的假设。我更正了源代码的那一部分,并且声明按照我最初想要的方式进行评估。我已经将它应用到其他练习中。这是一堂基础课,将对我的其余编程产生积极影响,再次感谢您。
    【解决方案2】:

    您已经(至少)得到了一个好的答案(我赞成)。但请让我详细说明“以防万一”:

    if(c == ' ' || c == '\n' || c == '\t') ... 您清楚地理解这一点:如果“空格”或“换行符”或“制表符”,那么“空格 == true”。

    ...但是... if (c != ' ' || c != '\n' || c != '\t') ... 说“如果不是空格……或者不是换行符……或者不是制表符”

    换句话说,'\n' 将评估为“空白 == false”...因为 '\n' 不是空白,也不是制表符。

    你真正的意思是if (c &amp;= ' ' &amp;&amp; c != '\n' &amp;&amp; c != '\t') ... ...或if (!(c == ' ' || c == '\n' || c == '\t')) ...

    换句话说,问题在于“C 语法”而不是“布尔逻辑”。

    这里有两个“重理论”的简短教程......但您可能会喜欢:

    【讨论】:

    • paulsm4,感谢您的进一步解释。我将这些链接放在我的书签中。视频中的布尔逻辑是我必须练习的。对位逻辑和一些我在批判性推理课上几乎不记得的东西似乎有点熟悉。
    猜你喜欢
    • 1970-01-01
    • 2021-10-07
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    相关资源
    最近更新 更多