Estou tentando ler uma linha de caracteres e imprimir o equivalente hexadecimal dos caracteres.
Por exemplo, se eu tenho uma string em que "0xc0 0xc0 abc123"
os 2 primeiros caracteres estão c0
em hexadecimal e os caracteres restantes estão abc123
em ASCII, então devo obter
c0 c0 61 62 63 31 32 33
No entanto, printf
usar %x
me dá
ffffffc0 ffffffc0 61 62 63 31 32 33
Como obtenho a saída desejada sem o "ffffff"
? E por que apenas c0 (e 80) tem o ffffff
, mas não os outros caracteres?
"\xc0\xc0abc123"
Respostas:
Você está vendo o
ffffff
porquechar
está conectado ao seu sistema. Em C, funções vararg comoprintf
promoverão todos os inteiros menores queint
aint
. Comochar
é um número inteiro (número inteiro assinado de 8 bits no seu caso), seus caracteres estão sendo promovidos porint
meio da extensão de sinal.Como
c0
e80
têm um 1 bit à esquerda (e são negativos como um inteiro de 8 bits), eles estão sendo estendidos de sinal, enquanto os outros em sua amostra não.Aqui está uma solução:
Isso irá mascarar os bits superiores e manter apenas os 8 bits inferiores que você deseja.
fonte
unsigned char
é uma instrução menor em gcc4.6 para x86-64 ...x
requer um tipo sem sinal, mas ch é promovido para int. O código correto seria simplesmente lançar ch para não assinado, ou usar um elenco de unsigned char e o especificador:hhx
.printf("%x", 0)
, nada é impresso.printf("%.2x", 0);
qual aumentará os caracteres mínimos desenhados para 2. Para definir um máximo, acrescente o. com um número. Por exemplo, você pode forçar apenas 2 caracteres desenhados fazendoprintf("%2.2x", 0);
printf("%x", ch & 0xff)
deveria ser melhor do que apenas usarprintf("%02hhX", a)
a resposta de @brutal_lobster ?Na verdade, há conversão de tipo para int. Além disso, você pode forçar o tipo para char usando o especificador% hhx.
Na maioria dos casos, você desejará definir o comprimento mínimo também para preencher o segundo caractere com zeros:
ISO / IEC 9899: 201x diz:
fonte
Você pode criar um caractere não assinado:
Imprimir vai dar
C5
e nãoffffffc5
.Apenas os caracteres maiores que 127 são impressos com o
ffffff
porque eles são negativos (o caractere é assinado).Ou você pode lançar o
char
durante a impressão:fonte
Você provavelmente está armazenando o valor 0xc0 em uma
char
variável, que provavelmente é um tipo com sinal , e seu valor é negativo (o conjunto de bits mais significativo). Então, ao imprimir, ele é convertido emint
, e para manter a equivalência semântica, o compilador preenche os bytes extras com 0xff, então o negativoint
terá o mesmo valor numérico do seu negativochar
. Para corrigir isso, basta lançar paraunsigned char
ao imprimir:fonte
Você pode usar
hh
para dizerprintf
que o argumento é um char sem sinal. Use0
para obter preenchimento zero e2
definir a largura como 2.x
ouX
para caracteres hexadecimais em maiúsculas / minúsculas.Edit : Se os leitores estão preocupados com a afirmação de 2501 de que este não é, de alguma forma, os especificadores de formato 'corretos', sugiro que leiam o
printf
link novamente. Especificamente:Quanto ao seu ponto sobre assinado vs não assinado, neste caso não importa, pois os valores devem ser sempre positivos e facilmente caber em um int assinado. De qualquer maneira, não há especificador de formato hexideximal assinado.
Edição 2 : ( edição "quando-admitir-que-você-está-errado"):
Se você ler o padrão C11 real na página 311 (329 do PDF), encontrará:
fonte
inttypes.h
char
eunsigned char
são promovidos aint
) [ en.cppreference.com/w/cpp/language/variadic_arguments] . Você só precisaria usar os especificadores PRI para coisas que não cabem em sua plataformaint
- por exemplounsigned int
.%x
está correto para unsigned int e não int. Os tipos char e unsigned char são promovidos a int. Além disso, não há garantia de que uint8_t seja definido como unsigned char.Provavelmente, você está imprimindo de uma matriz de caracteres assinada. Imprima a partir de um array de caracteres sem sinal ou mascare o valor com 0xff: por exemplo, ar [i] & 0xFF. Os valores c0 estão sendo estendidos por sinal porque o bit de sinal alto está definido.
fonte
Experimente algo assim:
O que produz isso:
fonte