【问题标题】:Case label does not reduce to an integer constant in C?案例标签不会减少为C中的整数常量?
【发布时间】:2012-10-13 17:04:20
【问题描述】:

我正在开发一款游戏,我运行了我的代码并得到了错误“case label does not reduce to an integer constant”。我想我知道这意味着什么,但我该如何解决呢?这是我的代码:

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

int player_cash[3] = {50};
char job[][20] {
    'A',
    'B',
    'C',
    "Donate",
    "Go to work",
    "Exit"
};
int jobs;

int main()
{
    while(player_cash[0] > 0) {
        printf("Please type A, B, C, Donate, Go to work, or Exit\n");
        switch(jobs) {

            case 'A':
            player_cash[0]-=5;
            player_cash[1]+=5;
            printf("Cash=%i\n\n", player_cash[0]);
            continue;

            case 'B':
            player_cash[0]-=5;
            player_cash[2]+=5;
            printf("Cash=%i\n\n", player_cash[0]);
            continue;

            case 'C':
            player_cash[0]-=5;
            player_cash[3]+=5;
            printf("Cash=%i\n\n", player_cash[0]);
            continue;

            case "Donate":
            player_cash[0]-=15; //Error here
            player_cash[1]+=5;
            player_cash[2]+=5;
            player_cash[3]+=5;
            printf("Cash donated\n\n");
            printf("Cash=%i\n\n", player_cash[0]);
            continue;

            case "Go to work":
            player_cash[0]+=10; //Error here
            printf("Work done\n\n");
            printf("Cash=%i\n\n", player_cash[0]);
            continue;

            case "Exit":
            printf("Thanks for playing!\n\n"); //Error here
            break;

            default:
            printf("Does not compute");
            continue;
        }
    }
        getchar();
        return 0;
}

所以,我希望用户做的是输入其中一个选项,然后执行与之对应的操作。我该如何解决这个问题?

【问题讨论】:

    标签: c arrays label switch-statement case


    【解决方案1】:

    您不能将字符串用作case 表达式:

    case "Donate":
    

    只能使用整数表达式,例如case 'A': 可以。

    从概念上讲,您有问题:jobsint,并且您正在测试字符串。如果您想允许用户输入字符串(多于一个字符),您需要保留一个字符串变量,并使用fgets 之类的东西来获取完整的输入行。

    【讨论】:

    • @Brandon,例如,您可以将if 语句与strcmp 结合使用。你的程序也有很多其他错误——例如,你实际上并没有读取任何输入。
    • @Brandon: if (strcmp(jobs, constant_1)) ... else if ...
    • @Vlad,是的。我猜只是老式的命名法。固定。
    • @Brandon:你是问如何使用if 还是如何使用strcmp?两者都是相当基本的东西。
    • 在这种情况下我将如何使用 fgets?
    【解决方案2】:

    您的一些大小写标签是字符(键入char,用's 表示)。这些 整数常量。

    其他标签是字符串文字(用"表示),其有效类型为const char *1那些不是整数常量,不能使用以这种方式。


    1 由于历史原因,它们通常可以像char * 一样使用,但不要尝试更改它们。否则。

    【讨论】:

      【解决方案3】:

      您不能将字符串与 c 进行比较。 "hello" == "hello" 不会按预期工作。 switch 只对基本类型进行简单的 c 比较。

      switch(jobs) {
      
              case 'A':
              player_cash[0]-=5;
              player_cash[1]+=5;
              printf("Cash=%i\n\n", player_cash[0]);
              continue;
      
              case 'B':
              player_cash[0]-=5;
              player_cash[2]+=5;
              printf("Cash=%i\n\n", player_cash[0]);
              continue;
      
              case 'C':
              player_cash[0]-=5;
              player_cash[3]+=5;
              printf("Cash=%i\n\n", player_cash[0]);
              continue;
      
              case 'D':
              player_cash[0]-=15; //Error here
              player_cash[1]+=5;
              player_cash[2]+=5;
              player_cash[3]+=5;
              printf("Cash donated\n\n");
              printf("Cash=%i\n\n", player_cash[0]);
              continue;
      
              case 'G':
              player_cash[0]+=10; //Error here
              printf("Work done\n\n");
              printf("Cash=%i\n\n", player_cash[0]);
              continue;
      
              case 'E':
              printf("Thanks for playing!\n\n"); //Error here
              break;
      
              default:
              printf("Does not compute");
              continue;
          }
      

      由于您只读取了getch() 中的一个字符,您可以比较这个值。 (但要求用户只输入一个字母,因为他输入“Donate”,getch() 会先读取 D,返回,然后读取 o,等等。)

      【讨论】:

        【解决方案4】:
        1. 您的作业数组的初始值设定项不一致(charconst char * 混合使用)

        2. 您不能将字符串文字用作大小写标签,因为 char 指针不是编译时常量。使用整数:

          enum jobType
          {
              jobA,
              jobB,
              jobC,
              jobDonate,
              jobGoToWork,
              jobExit,
              /* marker */
              jobInvalid
          };
          
          enum jobType typeOfJob(const char* const name)
          {
              int i;
              for (i=jobA; i!=jobInvalid; ++i)
                  if (0 == strcmp(jobNames[i], name))
                      return i;
              return i;
          }
          
        3. 另外,player_cash 短 1 个元素(并且在索引 [3] 处写入超出范围)


        代码示例还展示了如何避免一般的 gets 错误,进行一些基本的行尾修剪和不区分大小写的比较(Windows 上的 stricmp,IIRC):http://liveworkspace.org/code/227015a4e51126d55ca4eb1eea739b02

        #include<stdio.h>
        #include<stdlib.h>
        #include<string.h>
        
        int player_cash[4] = {50};
        
        enum jobType
        {
            jobA,
            jobB,
            jobC,
            jobDonate,
            jobGoToWork,
            jobExit,
            /* marker */
            jobInvalid
        };
        
        const char jobNames[][20] =
        {
            "A",
            "B",
            "C",
            "Donate",
            "Go to work",
            "Exit"
        };
        
        enum jobType typeOfJob(const char* const name)
        {
            int i;
            for (i=jobA; i!=jobInvalid; ++i)
        #ifdef CASE_SENSITIVE
                if (0 == strcmp(jobNames[i], name))
        #else
                if (0 == strcasecmp(jobNames[i], name))
        #endif
                    return i;
            return i;
        }
        
        const char* safer_gets()
        {
            static char input[1024];
            char *p;
            const char* t;
            const char trimAt[] = "\r\n\t ";
            fgets(input, sizeof(input), stdin);
        
            for (t=trimAt; *t; ++t)
                while(p = strrchr(input, *t)) 
                    *p = 0;
        
            return input;
        }
        
        int main()
        {
            const char* input;
            while(player_cash[0] > 0)
            {
                printf("Please type A, B, C, Donate, Go to work, or Exit\n");
                input = safer_gets();
        
                switch(typeOfJob(input))
                {
                case jobA:
                    player_cash[0]-=5;
                    player_cash[1]+=5;
                    printf("Cash=%i\n\n", player_cash[0]);
                    continue;
                case jobB:
                    player_cash[0]-=5;
                    player_cash[2]+=5;
                    printf("Cash=%i\n\n", player_cash[0]);
                    continue;
                case jobC:
                    player_cash[0]-=5;
                    player_cash[3]+=5;
                    printf("Cash=%i\n\n", player_cash[0]);
                    continue;
                case jobDonate:
                    player_cash[0]-=15; 
                    player_cash[1]+=5;
                    player_cash[2]+=5;
                    player_cash[3]+=5;
                    printf("Cash donated\n\n");
                    printf("Cash=%i\n\n", player_cash[0]);
                    continue;
                case jobGoToWork:
                    player_cash[0]+=10;
                    printf("Work done\n\n");
                    printf("Cash=%i\n\n", player_cash[0]);
                    continue;
                case jobExit:
                    printf("Thanks for playing!\n\n");
                    break;
                default:
                    printf("Does not compute");
                    continue;
                }
            }
            getchar();
            return 0;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多