【问题标题】:C switch case label value already appearedC switch case标签值已经出现
【发布时间】:2021-02-14 06:01:38
【问题描述】:

为什么 IDE 认为有错误?

"case 标签值已经出现在这个开关的第 9 行 C/C++(1578)"

int main(int argc, char const *argv[])
{
    for (int i = 0; i < argc; i++)
    {
        switch (*argv[i])
        {
            case 'drow': printf("drow detected");
            break;
            case 'drows': printf("drows detected"); //line 9
            break;
            case 'rows': printf("rows detected"); //error at the first apostrophe '
            break;
            default: printf("Unknown arg, skipping.");
            break;
        }  
    }
    return 0;
}

【问题讨论】:

  • 您希望通过'drow' 之类的表单获得什么?对于编译器,它是 'd' => 你有两次 case 'd'
  • 您不能在switch 语句中使用字符串。将字符串放在单引号中并不神奇,它只是将字符串变成chars;我很惊讶你的编译器没有给你一个错误或至少一个警告。使用一系列 if 语句,使用 strcmp 代替。
  • 无论如何*argv[i] 给出每个参数字符串的第一个字符 - 而不是字符串本身,即argv[i]

标签: c char switch-statement command-line-arguments c-strings


【解决方案1】:

您正在使用多字节字符常量作为标签

case 'drow':

它的值是int类型的实现定义。

C 标准,6.4.4.4 字符常量。

包含一个以上的整数字符常量的值 字符(例如,'ab'),或包含字符或转义序列 不映射到单字节执行字符,是 实现定义。

所以看起来常量'drow''drows' 具有相同的整数值。

编译器可能会发出一条消息,指出常量'drows' 对于它的类型来说太长了。

另一方面,switch语句中使用的表达式

switch (*argv[i])

不是多字节字符。所以无论如何switch语句没有意义。

您可以使用 if-else 语句来代替 switch 语句。例如

if ( strcmp( argv[i], "drow" ) == 0 )
{
    //...
}
else if ( strcmp( argv[i], "drows" ) == 0 )
{
    //...
}
else if ( strcmp( argv[i], "rows" ) == 0 )
{
    //...
}
else
{
    //...
}

【讨论】:

  • 哦,C,你为什么不直接把它变成一个错误……这个有什么用吗?
  • @Thomas 字符常量可以用作标签。
  • MSVC 确实会引发错误:error C2015: too many characters in constant.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-13
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
  • 1970-01-01
  • 2018-11-03
相关资源
最近更新 更多