Распечатка шестнадцатеричных значений массива char* в C дает нечетные значения для двоичного ввода

StackOverflow https://stackoverflow.com/questions/1773572

  •  21-09-2019
  •  | 
  •  

Вопрос

Вот странная проблема, которая меня немного поставила в тупик.

Программа написана на C89 и считывает файл в массив char* по 16 байт за раз (используя fread и размер sizeof(char)).Файл открывается с флагами «rb».Затем массив передается в функцию, которая принимает 16 шестнадцатеричных значений и помещает их в строку, где каждое значение отделяется пробелом.

Вот тут-то и начинается странность.Функция создает хороший шестнадцатеричный дамп по 16 байт за раз для входного текстового файла, который у меня есть.Но если я попробую это сделать на небольшом растровом изображении, все получится — в итоге я получу строку типа ffffff88, а не просто 88.

Шестнадцатеричные значения помещаются в выходную строку с помощью sprintf("%02x ", input[i]);в петле.

Почему это работает правильно для некоторых файлов, но не для других?

Это было полезно?

Решение

То, что вы видите, является результатом расширения знака от char к int, с использованием unsigned char * или кастинг в unsigned char до того, как будет выполнено приведение к int (неявно?), это должно решить вашу проблему.

Другие советы

В C символ рассматривается как знаковое значение, если только вы не укажете его как беззнаковое.Кажется, что когда вы передаете параметры функции, то, когда параметр является символом, он «дополняется» до размера обычного целого числа.Если вы не подскажете компилятору, что это следует делать беззнаковым способом, 128 станет 0xFFFFFF80 и так далее.

Таким образом, расширение знака происходит до того, как форматировщик печати сможет просмотреть значение.Это означает, что

printf("%02X", (unsigned) input[i]);

не решит вашу проблему, так как значение input[i] будет расширено по знаку, поэтому все значения от 128 до 255 обрабатываются как от -127 до -1 и становятся от 0xFFFFFF80 до 0xFFFFFF, а затем приводятся, тогда как

printf("%02X", ((unsigned char *) input)[i] );

подойдет, но он неуклюж и его трудно читать.Лучше всего сначала сделать тип ввода [] беззнаковым символом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top