Почему printf не печатает только один байт при печати в шестнадцатеричном формате? - PullRequest
33 голосов
/ 24 августа 2010

pixel_data является vector из char.

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

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

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

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

Ответы [ 5 ]

52 голосов
/ 24 августа 2010

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

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

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

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

Если char на вашей платформе подписано, то это преобразование преобразует отрицательные значения char в большие unsigned 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 );
7 голосов
/ 24 августа 2010

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

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

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

4 голосов
/ 24 августа 2010

Использование %hhx

printf("%#04hhx ", foo);
3 голосов
/ 24 августа 2010

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

2 голосов
/ 24 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...