输入:有一个int型数组,buf[29],共29个参数
1:8
2:2952790016
3:65536
4:268435456
5:0
6:0
7:0
8:184644090
9:1073741824
10:809477063
11:9109504
12:32
13:96478368
14:223139072
15:527044864
16:132645902
17:2417864707
18:99106829
19:1262617082
20:1073744048
21:0
22:50397155
23:637742555
24:3422552226
25:1879761324
26:2187026
27:8609824
28:268070512
29:386173440
输出:将buf转换成16进制,储存在char型字符串,char* message
1. 分配message存储空间
首先,使用sizeof()函数得到buf数组所占字节空间
int len= sizeof(buf);
两个16进制参量占1个字节(8比特),因此分配message空间是int型数组的两倍,即两个char字符(两个字节)表示int类型中1个字节。
int len= sizeof(buf)*2;
配置message空间
message = (char*) malloc(len);
2. int转换成hex
使用的是sprintf
函数。下面对sprintf
函数做简要描述:
- 功能:函数
sprintf()
用来作格式化的输出。 - 用法:此函数调用方式为
int sprintf(char *string, char *format, arg_list);
- 说明:函数
sprintf()
的用法和printf()
函数一样,只是sprintf()
函数给出第一个参数string
(一般为字符数组),然后再调用outtextxy()
函数将串里的字符显示在屏幕上。arg_list
为参数表,可有不定个数。通常在绘图方式下输出数字时可调用sprintf()
函数将所要输出的格式送到第一个参数,然后显示输出。 - 注1:因为C语言在进行字符串操作时不检查字符串的空间是否够大,所以可能会出现数组越界而导致程序崩溃的问题。即使碰巧,程序没有出错,也不要这么用,因为早晚会出错。所以一定要在调用
sprintf
之前分配足够大的空间给buf
。 - 注2:
sprintf()
函数arg_list
参数是无符号参量。
sprintf
函数和printf
函数打印的目的地不同,前者打印到字符串string
中,后者则直接在命令行上输出。例如如下:
- 把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
123
- 可以指定宽度,不足的左边补空格,右对齐:
sprintf(s, "%8d\n%8d", 123, 4567); //产生:" 123 4567"
123 4567
上图中指定8位,123和4567都不足8位,因此高位补空格。
- 指定宽度,不足的左边补空格,并左对齐:
sprintf(s, "%-8d\n%8d", 123, 4567); //产生:"123 4567"
123 4567
-也可以按照16 进制打印
右对齐
sprintf(s, "%8x", 4567); //小写16进制,宽度占8个位置,右对齐
11d7
左对齐
sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐
11d7
-16进制通常需要左边补零形式
sprintf(s, "%08X", 4567); //产生:"000011D7"
000011D7
上面以”%d”进行的10 进制打印同样也可以使用这种左边补0 的方式。
- 这里要注意一个符号扩展的问题
比如,假如我们想打印短整数(short)-1
的内存16 进制表示形式,在Win32 平台上,一个short
型占2 个字节,所以我们自然希望用4 个16 进制数字来打印它:
short si = -1;
sprintf(s, "%04X", si);
但产生
FFFFFFFF
因为spritnf
是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个%X
就能得知当初函数调用前参数压栈时被压进来的到底是个4字节的整数还是个2字节的短整数,所以采取了统一4字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32位的整数-1,打印时4个位置不够了,就把32位整数-1的8位16进制都打印出来了。如果你想看si
的本来面目,那么就应该让编译器做0扩展而不是符号扩展(扩展时二进制左边补0而不是补符号位):
sprintf(s, "%04X", (unsigned short)si);
或者:
unsigned short si = -1;
sprintf(s, "%04X", si);
输出
FFFF
sprintf
还可以按8进制打印整数字符串,使用%o
。注意8进制和16进制都不会打印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16进制或8进制表示。
- 另注
printf
函数不加“\n”是不会输出到终端的,printf
属于是行缓冲机制, 你要加一个换行符作为驱使信号;
printf("Hello World!\n");//有换行符。
printf("OK");//注意:没有换行符。
输出只会是
Hello World!
如果不写“\n”
依旧想输出,可以附加exit(0)
而不是_exit(0)
,exit
函数在_exit
函数的基础上进行了一些包装,在终止进程之前,它还会执行检查文件打开情况,清理I/O缓冲区等操作,例如把文件缓冲区的内容写回文件。
printf("Hello World!\n");//有换行符。
printf("OK");//注意:没有换行符。
_exit(0);//若用它,则不会输出OK。因为缓冲区的'OK"没有换行符,最终没有输出到终端,只输出Hello World,注意是在linux上。
exit(0);//若用它,则会输出OK.
或者更建议在每个最后不带\n
的printf
后面加fflush(stdout)
printf("OK");
fflush(stdout);
- 附格式字符查表
格式字符 | 意义 |
d | 以十进制形式输出带符号整数(正数不输出符号) |
o | 以八进制形式输出无符号整数(不输出前缀0) |
x,X | 以十六进制形式输出无符号整数(不输出前缀Ox) |
u | 以十进制形式输出无符号整数 |
f | 以小数形式输出单、双精度实数 |
e,E | 以指数形式输出单、双精度实数 |
g,G | 以%f或%e中较短的输出宽度输出单、双精度实数 |
c | 输出单个字符 |
s | 输出字符串 |
————————————
通过上述对sprintf
函数的功能介绍,选择该函数将int型buf数组转化成16进制字符串形式,代码如下:
for (int i = 0; i < 29; ++i) {
sprintf(message+i*8,"%08X",buf[i]);
printf("%d:",i);
puts(message+i*8);
}
for (int j = 0; j < 232; ++j) {
printf("%c", message[j]);
fflush(stdout);
}
输出结果为:
0:00000008
1:B0000000
2:00010000
3:10000000
4:00000000
5:00000000
6:00000000
7:0B0171FA
8:40000000
9:303FA3C7
10:008B0000
11:00000020
12:05C024A0
13:0D4CD500
14:1F6A1100
15:07E8040E
16:901DB003
17:05E8400D
18:4B4201FA
19:400008B0
20:00000000
21:0300FFE3
22:26032DDB
23:CC0000A2
24:700AE1AC
25:00215F12
26:00836020
27:0FFA6E70
28:17048A00
00000008B000000000010000100000000000000000000000000000000B0171FA40000000303FA3C7008B00000000002005C024A00D4CD5001F6A110007E8040E901DB00305E8400D4B4201FA400008B0000000000300FFE326032DDBCC0000A2700AE1AC00215F12008360200FFA6E7017048A00