한 줄의 문자를 읽은 다음 해당 문자에 해당하는 16 진수를 인쇄하려고합니다.
예를 들어, "0xc0 0xc0 abc123"처음 두 문자가 c016 진수이고 나머지 문자가 abc123ASCII 인 문자열이 있는 경우 다음을 얻어야합니다.
c0 c0 61 62 63 31 32 33그러나 printf사용 %x하면
ffffffc0 ffffffc0 61 62 63 31 32 33없이 원하는 출력을 얻으려면 어떻게합니까 "ffffff"? 그리고 왜 c0 (및 80)에만는 ffffff있지만 다른 문자는없는 이유는 무엇입니까?
답변
이 시스템에 서명되어 ffffff있기 때문에 char표시됩니다. C에서와 같은 가변 인자의 기능 printf보다는 모든 정수가 작은 촉진 int에 int. 이후 char정수 (귀하의 경우 8 비트 부호있는 정수)입니다, 당신의 문자가 승진되는 int부호 확장을 통해.
이후 c0및 80선도적 인 1 비트를 (그리고 8 비트 정수로 음) 샘플에서 다른 사람이하지 않는 동안, 그들은 로그인 확장되고있다.
char    int
c0 -> ffffffc0
80 -> ffffff80
61 -> 00000061해결책은 다음과 같습니다.
char ch = 0xC0;
printf("%x", ch & 0xff);이렇게하면 상위 비트는 가려지고 원하는 하위 8 비트 만 유지됩니다.
답변
실제로 int 로의 유형 변환이 있습니다. 또한 % hhx 지정자를 사용하여 유형을 char로 강제 지정할 수 있습니다.
printf("%hhX", a);대부분의 경우 두 번째 문자를 0으로 채우려면 최소 길이도 설정해야합니다.
printf("%02hhX", a);ISO / IEC 9899 : 201x는 다음과 같이 말합니다.
7 길이 수정 자와 그 의미는 다음과 같습니다. hh 다음 d, i, o, u, x 또는 X 변환 지정자가 부호있는 문자 또는 부호없는 문자 인수에 적용되도록 지정합니다 (인수는 정수 승격에 따라 승격됩니다. 그러나 그 값은 인쇄하기 전에 부호있는 문자 또는 부호없는 문자로 변환되어야합니다. 또는 다음
답변
서명되지 않은 문자를 만들 수 있습니다.
unsigned char c = 0xc5;이 줄 것이다 인쇄 C5하지 ffffffc5.
127보다 큰 문자 만 ffffff음수이기 때문에 인쇄됩니다 (char는 서명 됨).
또는 char인쇄 하는 동안 캐스팅 할 수 있습니다 .
char c = 0xc5;
printf("%x", (unsigned char)c);답변
char아마도 부호있는 유형 인 변수에 0xc0 값을 저장하고 있으며 값은 음수 (최상위 비트 세트)입니다. 그런 다음 인쇄 할 때로 변환되고 int의미 적 동등성을 유지하기 위해 컴파일러는 추가 바이트를 0xff로 채 웁니다. 따라서 음수 int는 음수 와 동일한 숫자 값을 갖습니다 char. 이 문제를 해결하려면 unsigned char인쇄 할 때 캐스트하십시오 .
printf("%x", (unsigned char)variable);답변
인수가 부호없는 문자임을 hh알리는 데 사용할 수 있습니다 printf. 사용은 0제로 패딩을 얻을 수 및 22로 폭을 설정 x또는 X이하 / 대문자 진수 문자.
uint8_t a = 0x0a;
printf("%02hhX", a); // Prints "0A"
printf("0x%02hhx", a); // Prints "0x0a"편집 : 독자가 이것이 ‘올바른’형식 지정자가 아니라는 2501의 주장에 대해 우려한다면 printf링크를 다시 읽으라고 제안 합니다. 구체적으로 특별히:
% c가 int 인수를 예상하더라도 가변 함수가 호출 될 때 발생하는 정수 승격 때문에 char를 전달하는 것이 안전합니다.
고정 너비 문자 유형 (int8_t 등)에 대한 올바른 변환 사양은 헤더
<cinttypes>(C ++) 또는<inttypes.h>(C)에 정의되어 있습니다 (PRIdMAX, PRIuMAX 등은 % jd, % ju 등과 동의어 임) .
부호있는 대 부호없는 것에 대한 그의 요점은이 경우 값이 항상 양수 여야하고 부호있는 정수에 쉽게 맞아야하므로 중요하지 않습니다. 어쨌든 서명 된 16 진수 형식 지정자는 없습니다.
편집 2 : ( “당신이 틀 렸음을 인정할 때”판) :
311 페이지 (PDF 329) 에서 실제 C11 표준 을 읽으면 다음 을 찾을 수 있습니다.
HH : 지정하는 다음가
d,i,o,u,x, 또는X변환 지시자는 적용signed char또는unsigned char인수 (인수는 정수 프로모션에 따른 증진 된 것이지만, 그 값으로 변환한다signed char또는unsigned char인쇄하기 전에); 또는 다음n변환 지정자가signed char인수 에 대한 포인터에 적용됩니다 .
답변
서명 된 문자 배열에서 인쇄하고있을 것입니다. 부호없는 문자 배열에서 인쇄하거나 0xff로 값을 마스크합니다 : 예 : ar [i] & 0xFF. 높은 (부호) 비트가 설정 되었기 때문에 c0 값이 부호 확장됩니다.
답변
다음과 같이 시도하십시오.
int main()
{
    printf("%x %x %x %x %x %x %x %x\n",
        0xC0, 0xC0, 0x61, 0x62, 0x63, 0x31, 0x32, 0x33);
}다음을 생성합니다.
$ ./foo
c0 c0 61 62 63 31 32 33