programing

printf는 char 배열에서 16진수 인쇄에 'FFFFFF'를 추가합니다.

topblog 2023. 10. 25. 21:58
반응형

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그들은 모두 그들의 승진 동안 연장되는 사인을 받고 있습니다.ints. 첫 번째 비트가 0일 때는 상관이 없습니다. 왜냐하면 다음과 같이 확장되기 때문입니다.0s.

0xAF2진법으로10101111첫번째 비트가.1, 그것을 건네줄 때에printf그것은 모두와 함께 확장됩니다.1s로 전환할 때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요소.프로모션 중에 서명된 비트가 전파되어 결과가 나타납니다.0xFFFFFFAFint활자로 친다면, 아마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

반응형