1

私は新進のCプログラマーであり、第2版K&R1.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」の後の2番目のスペース(0x20)を処理しているときに、どのようにしてword / nwをインクリメントできますか?2番目のifステートメントに到達したとしても、「state」変数を1(IN)に設定すると思います。ここで重要な何かが欠けています。私は与えられたどんな助けにも大いに感謝します。ありがとうございました。

4

2 に答える 2

7

との両方のchar がないため、everycharはこれを true と評価します。if(c != ' ' || c != '\n' || c != '\t')' ''\n''\t'

おそらく次のようになります。

if(c != ' ' && c != '\n' && c != '\t')
于 2012-05-09T19:40:47.027 に答える
1

あなたはすでに(少なくとも)1つの良い答えを持っています(私は賛成票を投じました)。しかし、「念のため」詳しく説明させてください。

if(c == ' ' || c == '\n' || c == '\t') ... あなたはこれを明確に理解しています:「スペース」または「改行」または「タブ」の場合、「空白==真」です。

...しかし... if (c != ' ' || c != '\n' || c != '\t') ...「スペースではない場合...または改行でない場合..またはタブではない場合」と言う

つまり、「\n」は「空白 == false」と評価されます...「\n」は空白ではなく、タブでもないためです。

あなたが本当に意味するのはif (c &= ' ' && c != '\n' && c != '\t') ... ...またはif (!(c == ' ' || c == '\n' || c == '\t')) ...

言い換えれば、問題は「ブール論理」よりも「C構文」の方が少ないということです。

「理論に重きを置いた」2 つの簡単なチュートリアルを次に示します。

于 2012-05-09T19:56:25.843 に答える