Я пытаюсь прочитать строку символов, а затем распечатать шестнадцатеричный эквивалент символов.
Например, если у меня есть строка "0xc0 0xc0 abc123"
, в которой первые 2 символа находятся c0
в шестнадцатеричном abc123
формате, а остальные символы - в ASCII, тогда я должен получить
c0 c0 61 62 63 31 32 33
Однако printf
использование %x
дает мне
ffffffc0 ffffffc0 61 62 63 31 32 33
Как мне получить желаемый результат без символа "ffffff"
? И почему только c0 (и 80) имеют ffffff
символы, а остальные нет?
"\xc0\xc0abc123"
Ответы:
Вы видите,
ffffff
потому чтоchar
подписано в вашей системе. В C функции vararg, такие как,printf
будут продвигать все целые числа меньше, чемint
доint
. Посколькуchar
это целое число (в вашем случае 8-битное целое число соint
знаком ), ваши символы продвигаются через расширение знака.Поскольку
c0
и80
имеют в начале 1-бит (и являются отрицательными как 8-битное целое число), они расширяются по знаку, в то время как другие в вашем примере нет.Вот решение:
Это замаскирует верхние биты и оставит только нижние 8 бит, которые вы хотите.
источник
unsigned char
преобразования в gcc4.6 для x86-64 на одну инструкцию меньше ...x
требуется тип без знака, но ch повышается до int. Правильный код будет просто отбрасывать ч до знака, или использовать приведение к беззнаковым символам и спецификаторам:hhx
.printf("%x", 0)
, ничего не печатается.printf("%.2x", 0);
увеличить минимальное количество нарисованных символов до 2. Чтобы установить максимальное значение, добавьте перед. с номером. Например, вы можете принудительно нарисовать только 2 символаprintf("%2.2x", 0);
printf("%x", ch & 0xff)
должна быть лучше , чем просто использоватьprintf("%02hhX", a)
как в @ brutal_lobster - х ответа ?Действительно, есть преобразование типа в int. Также вы можете принудительно использовать тип char, используя спецификатор% hhx.
В большинстве случаев вы также захотите установить минимальную длину, чтобы заполнить второй символ нулями:
ISO / IEC 9899: 201x говорит:
источник
Вы можете создать беззнаковый символ:
Печать даст
C5
и нетffffffc5
.Только символы больше 127 печатаются с
ffffff
отрицательным знаком (символ подписан).Или вы можете использовать
char
при печати:источник
Вероятно, вы сохраняете значение 0xc0 в
char
переменной, которая, вероятно, имеет знаковый тип, и ваше значение отрицательное (установлен самый старший бит). Затем при печати он преобразуется вint
, и для сохранения семантической эквивалентности компилятор дополняет дополнительные байты значением 0xff, поэтому отрицательный результатint
будет иметь то же числовое значение, что и ваш отрицательныйchar
. Чтобы исправить это, просто укажитеunsigned char
при печати:источник
Вы можете использовать,
hh
чтобы сказать,printf
что аргумент является беззнаковым символом. Используется0
для получения нулевого отступа и2
установки ширины на 2.x
илиX
для шестнадцатеричных символов нижнего / верхнего регистра.Изменить : если читатели обеспокоены утверждением 2501, что это как-то не «правильные» спецификаторы формата, я предлагаю им прочитать
printf
ссылку еще раз. В частности:Что касается его точки зрения о подписанном и беззнаковом, в этом случае это не имеет значения, поскольку значения всегда должны быть положительными и легко помещаться в подписанное int. В любом случае нет описателя шестнадцатеричного формата со знаком.
Редактировать 2 : (редакция «когда-признать-ты ошибаешься»):
Если вы прочитаете действующий стандарт C11 на странице 311 (329 PDF), вы обнаружите:
источник
inttypes.h
char
иunsigned char
повышаются доint
) [ en.cppreference.com/w/cpp/language/variadic_arguments] . Вам нужно будет использовать спецификаторы PRI только для вещей, которые не подходят для вашей платформы,int
напримерunsigned int
.%x
правильно для unsigned int, а не int. Типы char и unsigned char повышаются до int. Кроме того, нет гарантии, что uint8_t определен как unsigned char.Вероятно, вы печатаете из массива символов со знаком. Либо печатайте из массива беззнаковых символов, либо замаскируйте значение с помощью 0xff: например, ar [i] & 0xFF. Значения c0 расширяются по знаку, поскольку установлен старший (знаковый) бит.
источник
Попробуйте что-то вроде этого:
Что производит это:
источник