为什么我的 getchar() 做错了? (初始化元素不是常数)

问题描述 投票:0回答:1

代码:

#include <stdio.h>
#include <stdbool.h>

typedef enum{
  counting1,
  counting2,
  searching,
  possiblecom,
  possibleend,
} read_state;

bool issep(char a){
  return (a == ' ' || a == '\n' || a == '\t');
}

read_state state = searching;
int count = 0;
int c = getchar();

bool wasword = false;

while (c != -1)
{
  if(state == searching)
  {
    if(c == '{'){state = counting1;}
    else if(c == '('){state = possiblecom;}
  }else
  {
    if(state == counting2 && c == '*'){
      c = getchar();
      if(c == ')'){
        state = searching;
        if(wasword = true){
          count++;
        }
      }else{
        if (issep(c)){
          if (wasword == true){count++;}
          wasword = false;
        }else{wasword = true;}
      }
    }
    
    else if(state = counting1 && c == '}'){state = searching;}
    
    else if (state == counting1 || state == counting2){
      if (issep(c) == false){
        wasword = true;
      }
      else{
        if(wasword == true){count++;}
        wasword = false;
      }
    }
  }
  
  c = getchar();
  
  if(state = possiblecom){
    if(c == '*'){
      state = counting2;
      c = getchar();
      wasword = false;
    }else{state = searching;}
  }
}

printf("%d", count);

这些是错误:

1: comcount.c:24:9: error: initializer element is not constant
   24 | int c = getchar();
      |         ^~~~~~~
2: comcount.c:28:1: error: expected identifier or ‘(’ before ‘while’
   28 | while (c != -1)
      | ^~~~~
3:comcount.c:84:8: error: expected declaration specifiers or ‘...’ before string constant
   84 | printf("%d", count);
      |        ^~~~
  comcount.c:84:14: error: expected declaration specifiers or ‘...’ before ‘count’
   84 | printf("%d", count);
      |              ^~~~~

有几个问题:
我尝试用

int
替换
char
类型。我写了类似的东西:
int c = getchar(); \n n = c;

在正常情况下

int c = getchar();
可以工作,但在这段代码中有些东西破坏了它,我不知道是什么。

c initialization getchar
1个回答
0
投票

在注意到有关“主”函数中明显缺少代码封装的好评论后,我复制了您的代码,添加了缺少的语句以使程序逻辑的相关部分包含在“主”函数中,然后编译了代码。这导致编译器发出第一个需要解决的警告。

||=== Build: Release in WordSearch (compiler: GNU GCC Compiler) ===|
/home/craig/C_Programs/Console/WordSearch/main.c||In function ‘main’:|
/home/craig/C_Programs/Console/WordSearch/main.c|48|warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
/home/craig/C_Programs/Console/WordSearch/main.c|70|warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
/home/craig/C_Programs/Console/WordSearch/main.c|94|warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
||=== Build finished: 0 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|

这些警告是关于要在何处执行明显的相等测试 (==),但只有一个等号到位。

if(wasword = true)

else if(state = counting1 && c == '}')

if(state = possiblecom)

因此,根据编译器警告/建议对这些内容进行了重构和更正。

以下是代码的重构版本。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef enum
{
    counting1,
    counting2,
    searching,
    possiblecom,
    possibleend,
} read_state;

bool issep(char a)
{
    return (a == ' ' || a == '\n' || a == '\t');
}

int main()                                                          /* Per the comments - this was missing  */
{
    read_state state = searching;
    int count = 0;
    int c = getchar();

    bool wasword = false;

    while (c != '^')                                                /* Could not get the EOF/Ctrl-Z to work as the end of file read     */
    {
        if(state == searching)
        {
            if(c == '{')
            {
                state = counting1;
            }
            else if(c == '(')
            {
                state = possiblecom;
            }
        }
        else
        {
            if((state == counting2) && (c == '*'))                  /* Added parentheses to clarify testing logic   */
            {
                c = getchar();
                if(c == ')')
                {
                    state = searching;
                    if(wasword == true)                             /* Corrected equality testing   */
                    {
                        count++;
                    }
                }
                else
                {
                    if (issep(c))
                    {
                        if (wasword == true)
                        {
                            count++;
                        }
                        wasword = false;
                    }
                    else
                    {
                        wasword = true;
                    }
                }
            }

            else if((state == counting1) && (c == '}'))             /* Corrected equality testing   */
            {
                state = searching;
            }

            else if ((state == counting1) || (state == counting2))  /* Added parentheses to clarify testing logic   */
            {
                if (issep(c) == false)
                {
                    wasword = true;
                }
                else
                {
                    if(wasword == true)
                    {
                        count++;
                    }
                    wasword = false;
                }
            }
        }

        c = getchar();

        if(state == possiblecom)                                    /* Corrected equality testing   */
        {
            if(c == '*')
            {
                state = counting2;
                c = getchar();
                wasword = false;
            }
            else
            {
                state = searching;
            }
        }
    }

    printf("Count: %d\n", count);   /* Added some verbiage to explain what was being printed    */

    return 0;                       /* Per the comments - this was missing  */
}

利用正在进行某种类型的字数统计的一些假设,以下是发生文本输入的终端的测试输出。

craig@Vera:~/C_Programs/Console/WordSearch/bin/Release$ ./WordSearch 
{Now is the time 
for all good men
to come to the aid
of their country}^
Count: 15

仅供参考,我正在 Linux 系统上进行测试,无法使用“Ctrl-Z”文件结束功能,因此我替换了一个不太可能的字符“^”来模拟文本输入的结束。

我注意到的一件事是字数计数似乎减少了 1(如果计算短语的话,打印的计数为 15 个单词,而不是 16 个单词)。所以,这个程序可能需要进一步完善。

本次练习的主要收获可能是让您自己更加熟悉编译器产生的错误和警告。

© www.soinside.com 2019 - 2024. All rights reserved.