Значение метки регистра переключателя C уже появилось

#c #char #switch-statement #command-line-arguments #c-strings

#c #символ #switch-statement #аргументы командной строки #c-строки

Вопрос:

Почему IDE считает, что есть ошибка?

«значение метки регистра уже появилось в этом переключателе в строке 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;
}
  

Комментарии:

1. что вы ожидаете получить с помощью такой формы 'drow' ? для компилятора это ‘d’ => у вас есть два раза case 'd'

2. Вы не можете использовать строки в switch инструкции. Помещение строк в одинарные кавычки волшебным образом не делает это возможным, оно просто превращает строки в char s; Я удивлен, что ваш компилятор не выдает вам ошибку или, по крайней мере, предупреждение. Вместо этого используйте серию if инструкций using strcmp .

3. В любом случае *argv[i] выдает первый символ каждой строки аргумента, а не саму строку, которая есть argv[i] .

Ответ №1:

В качестве метки используется многобайтовая символьная константа

 case 'drow':
  

Его значением является реализация, определенная для типа int .

Стандарт C, 6.4.4.4 Символьные константы.

Значение целочисленной символьной константы, содержащей более одного символа (например, ‘ab’) или содержащей символ или управляющую последовательность, которая не сопоставляется с однобайтовым символом выполнения, определяется реализацией.

Таким образом, кажется, что константы 'drow' и 'drows' имеют одинаковое целочисленное значение.

Компилятор может выдать сообщение о том, что константа 'drows' слишком длинная для своего типа.

С другой стороны, выражение, используемое в инструкции switch

 switch (*argv[i])
  

не является многобайтовым символом. Так что в любом случае оператор switch не имеет смысла.

Вместо оператора switch вы можете использовать операторы if-else . Например

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

Комментарии:

1. О, C, почему ты просто не допустил эту ошибку … есть ли когда-нибудь для этого применение?

2. @Thomas В качестве метки может использоваться символьная константа.

3. MSVC выдает ошибку: error C2015: too many characters in constant .