【问题标题】:Can't get to understand word counting in C [closed]无法理解 C 中的字数统计 [关闭]
【发布时间】:2014-05-20 22:13:22
【问题描述】:

[已解决] 我最近问了一个关于一些我认为我非常理解的代码的问题。

但几天后,当我回顾修订时,新的问题来自同一段代码(来自 Brian. W. Kernighnan 的 THE C PROGRAMMING LANGUAGE 第二版(ISBN-13:978-8131704943))。

代码如下:

#include <stdio.h>

#define IN  1
#define OUT 0

main()
{
    int nw, c, state;
    state = OUT;
    nw = 0;
    while ((c = getchar()) != EOF)
    {
        if (c == ' ' || c == '\n' || c == '\t')
            state = OUT;
        else if (state == OUT)
        {
            state = IN;
            ++nw;
        }
    }
    printf("%d", nw);
}

所以我做了一些随机测试,发现了我无法解释或理解的东西:

  1. 为什么我有的时候代码不起作用

    state = OUTnw = 0 之后

当我通常运行此代码时,它给了我正确的编号。单词,但是当我交换state = OUT and nw = 0 的顺序时,它总是返回等于 0 的答案,为什么会这样? 我知道顺序在 C 中很重要,但为什么只有这个特定的顺序??

2.if-else语句的简要含义是什么?

3.Acc。到书国家变种。被定义为定义 getchar 是否在一个单词中,但我不明白 state var 的确切含义。这样做??

4.另外作者使用等价和相等是什么? 我注意到他在制定条件时使用等价,否则使用等价,对吗??

谢谢...

【问题讨论】:

  • 我认为您在这里错误地复制了代码。 if (c == ... 之后的 state == OUT; 行应该使用 = 而不是 ==
  • 这个问题似乎跑题了,因为纠正错字可以解决问题。
  • 对不起一个错字,(更正的脚本)但我真的很想了解这个脚本,请不要将其标记为离题......
  • 不是答案,但是将 C 源文件称为脚本非常令人困惑...另外,您确定问题的第 1 部分在编辑后仍然有效吗?
  • 请不要因为他的语言问题而抨击 OP。不是每个人都能说一口流利的英语。

标签: c if-statement boolean state getchar


【解决方案1】:

这是您发布的一些 cmets 的代码:

#include <stdio.h>
#define IN  1 // in the code below, whenever you see IN, it's replaced by 1
#define OUT 0 // same as IN, but for 0

int main(void) {
  int nw, c, state; // nw is the number of the words
  // c stands for the character we get from input and state is the state that are
  // currently.

  // init state as OUT
  state = OUT;
  // init counter to 0
  nw = 0;

  // while user doesn't give EOF
  while ((c = getchar()) != EOF) {

    // we found whitespace, newline or tab
    if (c == ' ' || c == '\n' || c == '\t')
      state = OUT;                            // put state as OUT,
    // so that we do not count them as words
    else if (state == OUT) {                  // enter here only if state is OUT
      // Now, we see that we found a letter/number, which means that a word
      // was typed by the user.

      // set state as IN, so that we remember that we are eating the characters of
      // the word given (in the next loops)
      state = IN;

      // increase the counter of the words
      ++nw;
    }
  }

  // print the number of words received by the user
  printf("%d", nw);
  return 0;
}

现在,让我们看一个示例输入:

sam
dad

当然输出(你应该从上面的 cmets 猜到)是:

2

让我们逐步运行(有趣的)代码输入sam

// input: "sam" (without the quotes)

while ((c = getchar()) != EOF) { // eat first character, i.e. 's'

  /****** 1st execution of the loop ********************/

  // 's' is not going into this if
  if (c == ' ' || c == '\n' || c == '\t')
    state = OUT;
  // first time we execute the loop so state is OUT,
  // thus we enter the loop
  else if (state == OUT) {

    // set state as IN
    state = IN;

    // increase the counter of the words
    ++nw;
  }

  /****************************************************/

  /****** 2nd execution of the loop ********************/
  // while loop's getchar() gives as 'a'

  // 'a' is not going into this if
  if (c == ' ' || c == '\n' || c == '\t')
    state = OUT;
  // state is IN, so we don't go into this loop
  else if (state == OUT) {
    state = IN;
    ++nw;
  }

  /****************************************************/


  /****** 3rd execution of the loop ********************/
  // same as 2nd, but for 'm'

  /****************************************************/


  /****** 4rth execution of the loop ********************/
  // while loop's getchar() gives as '\n'

  // '\n' is going into this if (the c == '\n' is true
  if (c == ' ' || c == '\n' || c == '\t')
    state = OUT;                // state sets to OUT

  // we are not going into this if else, since we already entered the above if!
  else if (state == OUT) {
    state = IN;
    ++nw;
  }

  /****************************************************/


  /****** 5th execution of the loop ********************/
  // while loop's getchar() gives as 'd' (first letter of dad)

  // 'd' is not going into this if
  if (c == ' ' || c == '\n' || c == '\t')
    state = OUT;
  // state is OUT, so we go into this loop
  else if (state == OUT) {
    // set state as IN
    state = IN;

    // increase counter
    ++nw;
  }

  /****************************************************/

  // and so on :)
}

首先确保您理解这一点,然后回答您自己提出的问题。 :)

另外,我们称之为代码,而不是脚本。不要急于进入脚本。

【讨论】:

  • 谢谢,但你能告诉我 state = in 是如何吃掉字符的吗?我也很抱歉造成混乱......
  • @ArchKudo 不客气。对我来说,没有造成任何问题。 :) getchar() 是吃角色的人。当stateIN 时,else if 部分将不会被执行(因为它的条件是假的)。此外,假设我们当时正在阅读一封信,state 等于IN 将视为未输入ifelse if,从而跳过该字母。希望对您有所帮助,并且答案足以让您接受。
  • Oo 终于明白了,所以它更像是在输入字母时进入 state = IN 所以它停止计算字母并在遇到空格或换行时再次开始计数.....谢谢你这么多……
  • 完全是@ArchKudo,但将“计数字母”更改为“计数单词”,因为代码旨在计算用户输入的单词数量。但我猜你只是打错字了。 :) 由于这是您相对较新的内容,但在阅读我所有的答案和 cmets 方面做得很好并最终理解了,我将支持您平衡 -1 的任务。 :)
猜你喜欢
  • 2014-11-04
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多