输入:有一个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
  • 注2sprintf()函数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.

或者更建议在每个最后不带\nprintf后面加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