2010-08-24 2 views
28

pixel_data является vector от char.Почему printf не распечатывает только один байт при печати hex?

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

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

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

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

+2

Смотрите также: http://stackoverflow.com/questions/3512749/memcpy-adds-ff-ff-ff-to-the-beginning-of-a-byte –

ответ

48

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

Вы должны явно привести символ к 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); 
+0

@charles. Спасибо за объяснение, почему ведущие 'f'! У стороннего API, который я использую, есть тип 'unsigned char', поэтому я изменил свое определение для' pixel_data', чтобы использовать его вместо этого и получить нужные мне результаты. – BeeBand

+1

@BeeBand: Будьте осторожны, просто переключение на 'unsigned char' может быть недостаточно. На большинстве платформ 'unsigned char' будет использоваться для' int', а не 'unsigned int'. –

+0

@Charles - когда я не перехожу на 'unsigned char' и просто делаю актеры, я все равно получаю те ведущие f. Думаю, мне нужно как изменить «unsigned int», так и использовать битовую маску, чтобы обеспечить ее работу на всех платформах. – BeeBand

3

Тогда length модификатор является минимальной длиной.

+0

так 1 - минимальная длина? Я думал, что модификатор длины был в байтах. – BeeBand

+3

Это длина символов. – leppie

+0

Извините, я просто не понимаю, что вы имеете в виду. Почему происходит то, что модификатор 'length' является минимальной длиной? – BeeBand

2

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

7

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

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

тогда ваш компилятор помещает шестигранного префикс для вас.

+0

фантастический! из-за незнания этого, я использовал отладчик ... – Tebe

3

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

printf("%#04hhx ", foo); 
+0

К сожалению, я использую стороннюю реализацию API 'printf', которая, похоже, не позволяет форматировать' hh'. Но хорошо знать - спасибо. – BeeBand

Смежные вопросы