Неожиданные результаты при просмотре кодов ASCII в C ++ - PullRequest
2 голосов
/ 11 января 2011

Бит кода ниже извлекает коды ASCII из символов.Когда я конвертирую символы в нормальном регионе ASCII, я получаю ожидаемое значение.Когда я конвертирую £ и € из расширенной области, я получаю загрузку 1, заполняющую INT, в котором я храню символ.

например, вывод ниже:

45 (ascii E, как и ожидалось) FFFFFF80 (расширенный ascii €, как и ожидалось, но дополненный единицами)

Это не вызывает у меня проблемы, но мне просто интересно, почему это происходит.Вот код ...

unsigned int asciichar[3];
    string cTextToEncode = "E€";
    for (unsigned int i = 0; i < cTextToEncode.length(); i++)
    {
        asciichar[i] = (unsigned int)cTextToEncode[i];
        cout << hex << asciichar[i] << "\n";    
    }

Кто-нибудь может объяснить, почему это так?Спасибо

Ответы [ 3 ]

7 голосов
/ 11 января 2011

в зависимости от реализации, символ может быть подписанным или неподписанным.В вашем случае они кажутся подписанными, поэтому 0x80 интерпретируется как -128 вместо 128, поэтому при приведении к целому числу оно становится 0xffffff80.

btw, это никак не связано с ASCII

5 голосов
/ 11 января 2011

Во-первых, в ASCII нет € (расширенного или иного), потому что евро не существовало на момент создания ASCII.Однако, несколько ASCII-дружественных 8-битных кодировок поддерживают символ €, но преобразование выполняется вашим редактором исходного кода (компилятор просто видит байт, который представляет € в вашем редакторе, но может быть чем-то другим,скажем, компьютер в Израиле).

Во-вторых, (unsigned int) приведение не извлекает кодировку ASCII символа.Они просто преобразуют значение базового числового типа char в целое число без знака.Это вызывает странные вещи, когда преобразованное значение является отрицательным - на вашем компиляторе char оказывается signed char, и, таким образом, символы со значением ASCII, превышающим 127, в итоге становятся отрицательными char значениями.* Вы должны сначала преобразовать в unsigned char, а затем в unsigned int.

1 голос
/ 11 января 2011

Вы должны быть осторожны при продвижении подписанных ценностей.

При продвижении подписанного символа в подписанный int учитывается первый бит (знаковый бит). Алгоритм выглядит примерно так:

1) Если у вас есть 1X-XX-XX-XX (двоичный символ, X - любая двоичная цифра), тогда int будет (начинается с 24) 1...1-1X-XX-XX-XX (двоичный) -> 0xFFFFFFYY (шестнадцатеричный)

2) если у вас есть 0X-XX-XX-XX (двоичный), то у вас будет (начинается с 24 нуля) 0...0-0X-XX-XX-XX (двоичный) -> 0x000000YY (шестнадцатеричный).

В вашем случае вы хотите постоянно применять правило № 2. Для этого вам нужно указать компилятору игнорировать первый бит (знаковый бит). Для этого вам нужно использовать unsigned char.

...