Стандартное поведение строк с символами в C ++ - PullRequest
1 голос
/ 23 сентября 2011

У меня есть проблема, которую я не понимаю. Я добавляю символы в стандартную строку. Когда я вынимаю их, напечатанное значение не соответствует ожиданиям.

int main (int argc, char *argv[])
{
    string x;
    unsigned char y = 0x89, z = 0x76;
    x += y;
    x += z;
    cout << hex << (int) x[0] << " " <<(int) x[1]<< endl;
}

Выход: ffffff89 76

Что я ожидал: 89 76

Есть идеи, что здесь происходит? И как мне это исправить?

Ответы [ 4 ]

4 голосов
/ 23 сентября 2011

Строковый оператор [] дает char, то есть значение со знаком. Когда вы преобразуете это в int для вывода, оно также будет подписанным значением.

Входное значение, приведенное к char, является отрицательным, и поэтому int также будет. Таким образом, вы видите результат, который вы описали.

2 голосов
/ 23 сентября 2011

Скорее всего char равно signed на вашей платформе, поэтому 0x89 и 0x76 становятся отрицательными, когда они представлены char.

Вы должны убедиться, что строка имеет unsigned char как value_type, поэтому это должно работать:

typedef basic_string<unsigned char> ustring; //string of unsigned char!

ustring ux;
ux += y;
ux += z;
cout << hex << (int) ux[0] << " " <<(int) ux[1]<< endl;

Он печатает то, что вы думаете напечатать:

89 76

Демо онлайн: http://www.ideone.com/HLvcv

1 голос
/ 23 сентября 2011

Вы должны учитывать тот факт, что char может быть подписано. Если вы повысите его до int напрямую, подписанное значение будет сохранено. Вместо этого сначала нужно преобразовать его в тип без знака той же ширины (т. Е. unsigned char), чтобы получить желаемое значение, а , а затем преобразуют это значение в целочисленный тип, чтобы получить правильный форматированный текст.

Собирая все вместе, вы хотите что-то вроде этого:

std::cout << (int)(unsigned char)(x[0]);

Или, используя приведение в стиле C ++:

std::cout << static_cast<int>(static_cast<unsigned char>(x[0]))
0 голосов
/ 23 сентября 2011

Число 0x89 равно 137 в десятичной системе. Он превышает the cap of 127 и теперь является отрицательным числом, и поэтому вы видите эти ffffff там. Вы можете просто insert (unsigned char) after the (int) cast. Вы получите требуемый результат.

-Sandip

...