Допустим, мы хотим увидеть char в шестнадцатеричном виде при помощи printf или аналогичной функции. Это бывает нужно для организации логирования дампов двоичных массивов при приёме/передаче данных, скажем.
Нас ждёт разочарование. char по умолчанию signed. Спецификатор для шестнадцатеричных чисел -- %x. Но он работает с числами размером с int. signed char будет преобразован в unsigned int, и все старшие биты будут забиты единичками из-за дополнительного кода. То есть, вместо 0x2F мы увидим 0xFFFFFF2F (при форматное строке "0x%02x").
Что же делать?
1. Забыть про массивы char. Использовать либо unsigned char, либо новомодный (лет пять-десять как) uint8_t.
2. Использовать двойное преобразование типов. Это лол. Я не ожидал, что это сработает:
printf( "0x%02x ",(unsigned int)(unsigned char)buffer[offset]);
Нас ждёт разочарование. char по умолчанию signed. Спецификатор для шестнадцатеричных чисел -- %x. Но он работает с числами размером с int. signed char будет преобразован в unsigned int, и все старшие биты будут забиты единичками из-за дополнительного кода. То есть, вместо 0x2F мы увидим 0xFFFFFF2F (при форматное строке "0x%02x").
Что же делать?
1. Забыть про массивы char. Использовать либо unsigned char, либо новомодный (лет пять-десять как) uint8_t.
2. Использовать двойное преобразование типов. Это лол. Я не ожидал, что это сработает:
printf( "0x%02x ",(unsigned int)(unsigned char)buffer[offset]);
30.04.2017 в 14:04
Подробности в мане: manpages.debian.org/jessie/manpages-dev/printf.3.en.html#The_length_modifier
А за упоминание дополнительного кода спасибо. Я, когда с единичками в верхних битах недавно столкнулся, почему-то не догадался, что это с знаковостью связано.
-- Minoru
30.04.2017 в 14:10
У меня данная ситуация касалась MSVS, но с ГНУ работать тоже приходится, изучу, спасибо.
>>Подробности в мане
Кто такая маня?))