printf 将额外的 `FFFFFF` 添加到字符数组的十六进制打印 [英] printf adds extra `FFFFFF` to hex print from a char array

查看:31
本文介绍了printf 将额外的 `FFFFFF` 添加到字符数组的十六进制打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的简化代码.我想从文件中提取一些二进制数据/流,并以十六进制格式将其打印到标准输出.

Consider the following simplified code bellow. I want to extract some binary data/stream from a file and print it to the standard output in Hexadecimal format.

我得到了额外的 3 个字节 0xFFFFFF.怎么了?额外的字节从哪里来?

I got extra 3 bytes 0xFFFFFF. What's wrong? From where did the extra bytes come?

输出

in:
        2000FFFFFFAF00690033005A00
out:
        2000FFFFFFAF00690033005A00

program.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 期间进行了符号扩展.当第一位是 0 时,这无关紧要,因为它会用 0s 扩展.

Sign extension. Your compiler is implementing char as a signed char. When you pass the chars to printf they are all being sign extended during their promotion to ints. When the first bit is a 0 this doesn't matter, because it gets extended with 0s.

0xAF 二进制是10101111 由于第一位是1,所以当把它传递给printf时在转换为 int 的过程中扩展了所有 1 使其成为 111111111111111111111111110101111,您拥有的十六进制值.

0xAF in binary is 10101111 Since the first bit is a 1, when passing it to printf it is extended with all 1s in the conversion to int making it 11111111111111111111111110101111, the hex value you have.

解决方法:使用unsigned char(而不是char)来防止调用中出现符号扩展

Solution: Use unsigned char (instead of char) to prevent the sign extension from occurring in the call

const unsigned char raw[] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0x00};

原始示例中的所有这些值都进行了符号扩展,只是 0xAF 是唯一一个在第一位带有 1 的值.

All of these values in your original example are being sign extended, it's just that 0xAF is the only one with a 1 in the first bit.

相同行为的另一个更简单示例(实时链接):

Another simpler example of the same behavior (live link):

signed char c = 0xAF; // probably gives an overflow warning
int i = c; // extra 24 bits are all 1
assert( i == 0xFFFFFFAF );

这篇关于printf 将额外的 `FFFFFF` 添加到字符数组的十六进制打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆