Почему printf не распечатывает только один байт при печати шестнадцатеричного кода?

pixel_data - это вектор из char .

Когда я выполняю printf ("0x% 1x", pixel_data [0]) , я ожидаю увидеть 0xf5 .

Но я получаю 0xfffffff5 , как будто я распечатываю 4-байтовое целое вместо 1 байта.

Почему это? Я дал printf char для печати - это всего лишь 1 байт, так почему же printf печатает 4?

NB. реализация printf заключена в сторонний API, но просто интересно, является ли это функцией стандартного printf ?

34
задан BeeBand 24 August 2010 в 11:26
поделиться

5 ответов

Вы, вероятно, получаете доброкачественную форму неопределенного поведения, потому что модификатор % x ожидает ] unsigned int параметр и char обычно будут преобразованы в int при передаче в функцию varargs .

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

printf(" 0x%1x ", (unsigned)pixel_data[0] );

Обратите внимание, что ширина поля , равная единице, не очень полезна. Он просто указывает минимальное количество отображаемых цифр, и в любом случае потребуется хотя бы одна цифра.

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

например.

printf(" 0x%x ", (unsigned)(unsigned char)pixel_data[0] );

или

printf(" 0x%x ", (unsigned)pixel_data[0] & 0xffU );
54
ответ дан 27 November 2019 в 16:36
поделиться

Спецификатор ширины в printf на самом деле является min-width. Вы можете выполнить printf ("0x% 2x", pixel_data [0] & 0xff) , чтобы напечатать младший байт (примечание 2, чтобы напечатать два символа, если pixel_data [0] , например, 0xffffff02 ).

2
ответ дан 27 November 2019 в 16:36
поделиться

Тогда модификатор length - это минимальная длина.

3
ответ дан 27 November 2019 в 16:36
поделиться

Лучше использовать флаги стандартного формата

printf(" %#1x ", pixel_data[0] );

, тогда компилятор поставит шестнадцатеричный префикс за вас.

7
ответ дан 27 November 2019 в 16:36
поделиться

Используйте %hhx

printf("%#04hhx ", foo);
4
ответ дан 27 November 2019 в 16:36
поделиться