Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 字符的十六进制表示法不正确,但字符的无符号表示法正确_C_File_Hex - Fatal编程技术网

C 字符的十六进制表示法不正确,但字符的无符号表示法正确

C 字符的十六进制表示法不正确,但字符的无符号表示法正确,c,file,hex,C,File,Hex,我正在编写一个函数,用于打印给定文件的“hextump”。功能如下所述: bool printhexdump (FILE *fp) { long unsigned int filesize = 0; char c; if (fp == NULL) { return false; } while (! feof (fp)) { c = fgetc (fp); if (filesize % 16 == 0)

我正在编写一个函数,用于打印给定文件的“hextump”。功能如下所述:

bool printhexdump (FILE *fp) {
    long unsigned int filesize = 0;
    char c;

    if (fp == NULL) {
        return false;
    }

    while (! feof (fp)) {
        c = fgetc (fp);
        if (filesize % 16 == 0) {
            if (filesize >= 16) {
                printf ("\n");
            }
            printf ("%08lx  ", filesize);
        }
        printf ("%02hx ", c);
        filesize++;
    }

    printf ("\n");
    return true;
}
但是,在某些文件上,似乎会打印某些无效的整数表示形式,例如:

00000000  4d 5a ff90 00 03 00 00 00 04 00 00 00 ffff ffff 00 00
00000010  ffb8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030  00 00 00 00 00 00 00 00 00 00 00 00 ff80 00 00 00
00000040  ffff
除了由于
EOF
字符导致的最后一个
ffff
之外,
ff90
ffff
ffb8
等都是错误的。但是,如果我将
char
更改为
unsigned char
,则会得到正确的表示形式:

00000000  4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00
00000010  b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030  00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00
00000040  ff
为什么会发生上述行为


Edit:由于格式说明符不变,因此
printf()
c
的处理应该是相同的。因此,我不确定
字符
如何得到符号扩展,而
无符号字符
不会得到符号扩展?

因为在
无符号字符
中,最高有效位的含义与
有符号字符
的含义不同


例如,二进制中的
0x90
10010000
,它是
144
十进制,无符号,但有符号它是
-16
十进制。

因为在
无符号字符中,最高有效位的含义与
有符号字符的含义不同


例如,二进制中的
0x90
10010000
,它是
144
十进制,无符号,但有符号它是
-16
十进制。

char
可以是有符号类型,在这种情况下,值
0x80
0xff
在传递到
printf
之前进行符号扩展

(char)0x80是扩展到-128的符号,在无符号的简短形式中是0xff80

[编辑]更清楚地了解促销活动;存储在字符中的值是8位,在该8位表示中,类似0x90的值将表示-112或114,这取决于字符是有符号的还是无符号的。这是因为对于有符号类型,最高有效位作为符号位,对于无符号类型,最高有效位作为幅值位。如果设置了该位,它要么使值为负值(减去128),要么使值变大(加128),这取决于它是否是有符号类型

从char到int的提升总是会发生,但是如果char是有符号的,那么将其转换为int需要将符号位展开到int的符号位,以便int表示与char相同的值

然后,
printf
获得了它,但它不知道原始类型是有符号的还是无符号的,也不知道它以前是字符。它所知道的是,格式说明符用于无符号十六进制短字符,因此它将该数字打印为无符号短字符。16位
int
中-112的位模式为
1111110010000
,格式为十六进制,即ff90


如果您的字符是无符号的,则0x90不表示负值,并且当您将其转换为int时,不需要更改int中的任何内容以使其表示相同的值。位模式的其余部分都是零,并且
printf
不需要这些数字来正确显示数字。

char
可以是有符号类型,在这种情况下,值
0x80
0xff
在传递到
printf
之前进行符号扩展

(char)0x80是扩展到-128的符号,在无符号的简短形式中是0xff80

[编辑]更清楚地了解促销活动;存储在字符中的值是8位,在该8位表示中,类似0x90的值将表示-112或114,这取决于字符是有符号的还是无符号的。这是因为对于有符号类型,最高有效位作为符号位,对于无符号类型,最高有效位作为幅值位。如果设置了该位,它要么使值为负值(减去128),要么使值变大(加128),这取决于它是否是有符号类型

从char到int的提升总是会发生,但是如果char是有符号的,那么将其转换为int需要将符号位展开到int的符号位,以便int表示与char相同的值

然后,
printf
获得了它,但它不知道原始类型是有符号的还是无符号的,也不知道它以前是字符。它所知道的是,格式说明符用于无符号十六进制短字符,因此它将该数字打印为无符号短字符。16位
int
中-112的位模式为
1111110010000
,格式为十六进制,即ff90


如果您的字符是无符号的,则0x90不表示负值,并且当您将其转换为int时,不需要更改int中的任何内容以使其表示相同的值。位模式的其余部分都是零,并且
printf
不需要这些数字来正确显示数字。

是否对
char
进行签名取决于平台。这意味着符号位可以扩展,也可以不扩展,这取决于您的机器,因此您可以得到不同的结果


但是,使用
无符号字符
可以确保没有符号扩展(因为不再有符号位)。

是否对
字符
进行签名取决于平台。这意味着符号位可以扩展,也可以不扩展,这取决于您的机器,因此您可以得到不同的结果


但是,使用
无符号字符
可以确保没有符号扩展(因为不再有符号位)。

问题只是由格式引起的<代码>%h02x
接受一个整数。当你接受一个低于128的字符时,一切正常,它是正数,转换为整数时不会改变

现在,让我们把一个字符在128以上,比如说代码> 0x90。作为无符号字符,其值为144,将转换为144的int值,并在

90
处打印。但是作为有符号字符,它的值是-
char c;
printf ("%02x ", (unsigned char) c);
// or
printf ("%02hhx ", c);

// or
unsigned char c;
printf ("%02x ", c);
// or
printf ("%02hhx ", c);