printf는 char 배열에서 16진수 인쇄에 'FFFFFF'를 추가합니다.
아래와 같은 단순화된 코드를 고려합니다.파일에서 이진 데이터/스트림을 추출하여 16진수 형식으로 표준 출력에 인쇄하고자 합니다.
3바이트를 더 받았습니다.0xFFFFFF
.뭐가 잘못됐나요?여분의 바이트는 어디서 왔습니까?
산출량
in:
2000FFFFFFAF00690033005A00
out:
2000FFFFFFAF00690033005A00
프로그램.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int i;
char raw[10] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0x00};
FILE *outfile;
char *buf;
printf("in:\n\t");
for( i=0; i<10; i++ )
printf("%02X", raw[i]);
outfile = fopen("raw_data.bin", "w+b");
fwrite(raw, 1, 10, outfile);
buf = (char *) malloc (32 * sizeof(char));
fseek(outfile, 0, SEEK_SET);
fread(buf, 1, 10, outfile);
printf("\nout:\n\t");
for( i=0; i<10; i++ )
printf("%02X", buf[i]);
printf("\n");
fclose(outfile);
return 0;
}
사인 내선.컴파일러가 구현 중입니다.char
로서signed char
. 당신이 문자를 전달할 때printf
그들은 모두 그들의 승진 동안 연장되는 사인을 받고 있습니다.int
s. 첫 번째 비트가 0일 때는 상관이 없습니다. 왜냐하면 다음과 같이 확장되기 때문입니다.0
s.
0xAF
2진법으로10101111
첫번째 비트가.1
, 그것을 건네줄 때에printf
그것은 모두와 함께 확장됩니다.1
s로 전환할 때int
해내기11111111111111111111111110101111
,어느 것이0xFFFFFFAF
, 당신이 가지고 있는 16진수 값.
해결책 : 사용unsigned char
(instead.char
) 통화 중에 부호 확장이 발생하지 않도록 합니다.
const unsigned char raw[] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0x00};
원래 예에서 이러한 값은 모두 부호 확장입니다. 다만,0xAF
유일하게 A와 함께 있습니다.1
처음에
동일한 동작의 또 다른 간단한 예(라이브 링크):
signed char c = 0xAF; // probably gives an overflow warning
int i = c; // extra 24 bits are all 1
assert( i == 0xFFFFFFAF );
그것은 서명된 문자에서 서명된 정수로 변환될 때 0xAF가 음수이기 때문입니다(이것은 부호 확장입니다).%02X
형식은 서명되지 않은 인수를 위한 것이며 변환된 값을 다음과 같이 출력합니다.FFFFFFAF
.
printf 때문에 추가 문자가 나타납니다.%x
는 값에서 자리 수를 자동으로 자르지 않습니다.음이 아닌 값도 부호가 확장되지만, 그것은 단지 0비트를 더하는 것이고 그 값은 2개의 16진수에 들어맞기 때문에 printf.%02
두 자리 출력으로 할 수 있습니다.
참고로 2개의 C 방언이 있습니다. 하나는 평범합니다.char
서명되어 있고, 서명되어 있지 않은 곳에 하나.당신의 것에는 서명이 되어 있습니다.gcc 및 clang 지원과 같은 옵션을 사용하여 변경할 수 있습니다.-funsigned-char
그리고.-fsigned-char
.
그printf()
는 가변 함수이고 추가 인수입니다 (에 해당합니다)....
프로토타입의 일부)는 기본 인수 프로모션의 대상이 되므로char
로 승격됩니다.int
.
당신의char
서명했습니다1. 2의 보어 표현에서 가장 의미 있는 비트가 1로 설정됩니다.0xAF
요소.프로모션 중에 서명된 비트가 전파되어 결과가 나타납니다.0xFFFFFFAF
int
활자로 친다면, 아마sizeof(int) = 4
당신의 구현에 있어서.
그건 그렇고, 당신은 정의되지 않은 행동을 호출하고 있습니다.%X
형식 지정자는 유형의 개체에 사용해야 합니다.unsigned int
아니면 적어도 을 위해int
설정되지 않은 MSB를 사용합니다(이것은 일반적이고 널리 인정되는 관행입니다).
제안한 대로 모호하지 않은 사용을 고려할 수 있습니다.unsigned char
형.
1) 구현은 서명된 표현과 서명되지 않은 표현 중 하나를 선택할 수 있습니다.char
. 는 것이 꽤 일반적입니다.char
서명이 되어 있지만 지구상의 모든 다른 컴파일러에 대해 당연하게 생각할 수는 없습니다.젠스의 대답에서 언급된 바와 같이, 그들 중 일부는 이 두 가지 모드 중 하나를 선택할 수 있습니다.
언급URL : https://stackoverflow.com/questions/31090616/printf-adds-extra-ffffff-to-hex-print-from-a-char-array
'programing' 카테고리의 다른 글
R's magrittr의 python에서 %>%와 같은 기능 파이프 (0) | 2023.10.25 |
---|---|
클랑이 더 많이 사용되지 않는 이유는 무엇입니까? (0) | 2023.10.25 |
Mariadb - 확장된 삽입 실행 시간이 점차적으로 증가하고 있습니다. (0) | 2023.10.25 |
CDN 사용 대 NPM에서 라이브러리 설치 (0) | 2023.10.25 |
브라우저 캐시를 프로그래밍적으로 비우는 방법은? (0) | 2023.10.25 |