printf的增加了额外的`FFFFFF`为十六进制的字符数组打印 [英] printf adds extra `FFFFFF` to hex print from a char array
问题描述
考虑以下简化code波纹管。我想从文件中提取一些二进制数据/流,并将其打印到十六进制格式的标准输出。
我得到了额外的3个字节 0XFFFFFF
。怎么了?从哪儿来的额外的字节来了?
输出
中:
2000FFFFFFAF00690033005A00
出:
2000FFFFFFAF00690033005A00
program.c
的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;INT主(INT ARGC,字符** argv的){ INT I;
烧焦原料[10] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0×00};
FILE * outfile的;
字符* BUF; 的printf(中:\\ n \\ t的);
对于(I = 0; I&小于10;我+ +)
的printf(%02X,原[I]); OUTFILE = FOPEN(raw_data.bin,W + B); FWRITE(原始的,1,10,OUTFILE); BUF =(字符*)malloc的(32 * sizeof的(炭));
fseek的(OUTFILE,0,SEEK_SET);
的fread(BUF,1,10,outfile中); 的printf(\\ NOUT:的\\ n \\ t的);
对于(I = 0; I&小于10;我+ +)
的printf(%02X,BUF [I]); 的printf(\\ n); FCLOSE(OUTFILE);
返回0;
}
符号扩展。你的编译器正在实施字符
为符号字符
。当你传递的printf 的字符为他们都被签上自己的promootion期间向
INT
秒。当第一位是0,这并不重要,因为它可以让用 0
s扩展。
0xAF执行
二进制是 10101111
由于第一位是一个 1
,将它传递给时的printf
它与所有的 1
S IN转换扩展到 INT
使其 11111111111111111111111110101111
,你有十六进制值。
而是使用 unsigned char型
来prevent在通话中出现的符号扩展形式
const的无符号字符原料[] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0×00};
所有你原来的例子,这些值都被符号扩展,它只是 0xAF执行
是唯一一个以 1
中的第一位。
同样的行为的另一个简单的例子(假设炭签字)
的char c = 0xAF执行; //大概给出了一个溢出警告
INT I = C; //额外的24位全部为1
断言(我== 0xFFFFFFAF);
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.
I got extra 3 bytes 0xFFFFFF
. What's wrong? From where did the extra bytes come?
output
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;
}
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 promootion to int
s. When the first bit is a 0 this doesn't matter, because it gets extended with 0
s.
0xAF
in binary is 10101111
Since the first bit is a 1
, when passing it to printf
it is extended with all 1
s in the conversion to int
making it 11111111111111111111111110101111
, the hex value you have.
Instead use unsigned char
to prevent the sign extension form occurring in the call
const unsigned char raw[] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0x00};
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 (assuming char is signed)
char c = 0xAF; // probably gives an overflow warning
int i = c; // extra 24 bits are all 1
assert( i == 0xFFFFFFAF );
这篇关于printf的增加了额外的`FFFFFF`为十六进制的字符数组打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!