Хорошо, любопытная ошибка при сборке с Visual Studio Ultimate 2012 (вероятно, проблема с ANSI, unicode и т. Д.) В коде ...

switch (input[index])
{
    case 'א': // Alef Hebrew character
        if (/*conditional*/) 
        {
            // Do stuff.
        }
    break;

    case 'ב': // Beth Hebrew character
        if (/*conditional*/)
        {
            //Do stuff
        }
    break;

    default:
    {
            //Do some other stuff.
    }
    break;

}

Второй параметр case генерирует ...

Error C2196: case value '?' already used

Если возможно, простое исправление.

c++ c
4
loumbut5 6 Сен 2016 в 11:49

3 ответа

Лучший ответ

Символ 'א' не может поместиться в char. Обычно это занимает несколько байтов, поэтому 'א' представляет собой "многосимвольный литерал", как и 'ab' (ПРИМЕЧАНИЕ: используется ОДНА кавычка).

«Многосимвольный литерал» имеет тип int и значение, определяемое реализацией. Кроме того, разные многосимвольные литералы могут иметь одно и то же значение, поскольку существует бесконечное количество многосимвольных литералов.

В вашем случае, очевидно, ваш компилятор обработал и 'א', и 'ב' как '?', поэтому он выдает ошибку, так как одно и то же значение ('?') появляется после case метки дважды в одном switch.

Предположим, вы используете wchar_t, исправление уже дано Иваном.

Если вы используете char, то א является мультихарактарной строкой вместо char. Вы можете использовать функцию сравнения строк, чтобы проверить, появляется ли א в определенном index из input:

const int ONE = 1;
if (strncmp(input+index, "א", sizeof("א") - ONE) == 0) {
      // Alef Hebrew character
    if (/*conditional*/) 
    {
       // Do stuff.
    }
} else if (strncmp(input+index, "ב", sizeof("ב") - ONE) == 0) {
     // Beth Hebrew character
    if (/*conditional*/)
    {
        //Do stuff
    }
} else {
    // default:
    // Do 
}
0
fefe 6 Сен 2016 в 10:42

Предполагая, что input - это массив wchar_t, ваша проблема в том, что вы сравниваете широкий символ с узким символьным литералом.

Как сказал PeterT в комментариях:

Если вы сохраните файл в кодировке utf-8, то א будет 0xD790, а ב будет 0xD791, поэтому, если input[index] имеет тип char, оба будут пытаться совпадение 0xD7.

Вот почему вы получаете указанную вами ошибку. (char имеет достаточно места для хранения значения ASCII, а остальное опущено)


Вы можете исправить это, поставив перед литералами заглавную букву L (превратив их в широкие символы).

case L'א': // Alef Hebrew character
    if (/*conditional*/) 
    {
        // Do stuff.
    }
break;

case L'ב': // Beth Hebrew character
    if (/*conditional*/)
    {
        //Do stuff
    }
break;

Кроме того, вам необходимо убедиться, что ваш исходный файл сохранен в кодировке Unicode, и ваш компилятор знает, как с этим работать.

В качестве альтернативы вы можете просто избежать значения Unicode следующим образом:

case L'\u05D0': // Aleph Hebrew character
// ...
case L'\u05D1': // Beth Hebrew character
6
Community 23 Май 2017 в 12:22

C (и C ++), как известно, плохо справляются с обработкой Unicode. Проблема в том, что вы пытаетесь уместить еврейский символ в char. Но char (один байт) достаточно широк только для ASCII.

Если вы используете современные (читайте, по крайней мере, C ++ 11) версии C ++, следуйте этому ответу.

Если вы используете C, вы, вероятно, захотите использовать ICU IBM библиотека.

3
Community 23 Май 2017 в 12:08