如何在缓冲区中打印数据,而不考虑给定长度之间的零
How to print data in a buffer irrespective of zeros in between till the given length
我写了一个简单的程序来读取一个数据包直到第 3 层并以十六进制格式打印它。
我以十六进制格式输入。我的输出应该和这个一样。
输入:
45 00 00 44 ad 0b 00 00 40 11 72 72 ac 14 02 fd ac 14
00 06 e5 87 00 35 00 30 5b 6d ab c9 01 00 00 01
00 00 00 00 00 00 09 6d 63 63 6c 65 6c 6c 61 6e
02 63 73 05 6d 69 61 6d 69 03 65 64 75 00 00 01
00 01
我能够读取数据包。这里是 gdb
中的十六进制转储
(gdb) p packet
= 0x603240 "E"
(gdb) x/32x 0x603240
0x603240: 0x00440045 0x00000000 0x00400b0e 0x00000000
0x603250: 0x00603010 0x0035e587 0xe3200030 0x63206261
0x603260: 0x31302039 0x20303020 0x30203030 0x30302031
0x603270: 0x20303020 0x30203030 0x30302030 0x20303020
0x603280: 0x36203930 0x33362064 0x20333620 0x36206336
0x603290: 0x63362035 0x20633620 0x36203136 0x32302065
0x6032a0: 0x20333620 0x30203337 0x64362035 0x20393620
0x6032b0: 0x36203136 0x39362064 0x20333020 0x36203536
但是当我尝试使用 %s 在控制台中打印数据包时,由于中间为零,我看不到整个数据包。但是我想把它打印到数据包的长度(我把它作为打印函数的输入)。
控制台上的输出是:
packet: E
我的打印功能是这样的。
void print(char *packet, int len) {
printf("packet: ");
printf("%s\n\n" , packet );
}
你能告诉我任何其他方法来打印数据包直到 len(打印功能的输入)。
PS: 阅读l3资料我没有完成。因此,在数据包 l3 的 gdb 中,信息因我的输入而异。
C 中的 string 定义为以 '[=11=]'
(0 字节)结尾的字符序列,以及 %s
转换说明符printf()
用于 字符串 。所以你的问题的解决方案是做一些其他的事情来打印二进制字节。例如,如果你想打印它们的十六进制值,你可以像这样改变你的打印函数:
void print(unsigned char *packet, size_t len)
{
for (size_t i = 0; i < len; ++i) printf("%02hhx ", packet[i]);
puts("");
}
注意我在这里也更改了类型:
char
可以签名。如果你想处理原始字节,最好总是使用 unsigned char
.
int
对于某个尺寸来说可能太小了,请始终使用 size_t
,它可以保证在您的平台上容纳任何可能的尺寸。
如果你真的想打印编码字符(二进制数据不太可能),你可以在printf()
中使用%c
,或者使用putchar()
函数,或者fwrite()
整个块到 stdout
.
我写了一个简单的程序来读取一个数据包直到第 3 层并以十六进制格式打印它。 我以十六进制格式输入。我的输出应该和这个一样。
输入:
45 00 00 44 ad 0b 00 00 40 11 72 72 ac 14 02 fd ac 14
00 06 e5 87 00 35 00 30 5b 6d ab c9 01 00 00 01
00 00 00 00 00 00 09 6d 63 63 6c 65 6c 6c 61 6e
02 63 73 05 6d 69 61 6d 69 03 65 64 75 00 00 01
00 01
我能够读取数据包。这里是 gdb
中的十六进制转储(gdb) p packet
= 0x603240 "E"
(gdb) x/32x 0x603240
0x603240: 0x00440045 0x00000000 0x00400b0e 0x00000000
0x603250: 0x00603010 0x0035e587 0xe3200030 0x63206261
0x603260: 0x31302039 0x20303020 0x30203030 0x30302031
0x603270: 0x20303020 0x30203030 0x30302030 0x20303020
0x603280: 0x36203930 0x33362064 0x20333620 0x36206336
0x603290: 0x63362035 0x20633620 0x36203136 0x32302065
0x6032a0: 0x20333620 0x30203337 0x64362035 0x20393620
0x6032b0: 0x36203136 0x39362064 0x20333020 0x36203536
但是当我尝试使用 %s 在控制台中打印数据包时,由于中间为零,我看不到整个数据包。但是我想把它打印到数据包的长度(我把它作为打印函数的输入)。
控制台上的输出是:
packet: E
我的打印功能是这样的。
void print(char *packet, int len) {
printf("packet: ");
printf("%s\n\n" , packet );
}
你能告诉我任何其他方法来打印数据包直到 len(打印功能的输入)。
PS: 阅读l3资料我没有完成。因此,在数据包 l3 的 gdb 中,信息因我的输入而异。
C 中的 string 定义为以 '[=11=]'
(0 字节)结尾的字符序列,以及 %s
转换说明符printf()
用于 字符串 。所以你的问题的解决方案是做一些其他的事情来打印二进制字节。例如,如果你想打印它们的十六进制值,你可以像这样改变你的打印函数:
void print(unsigned char *packet, size_t len)
{
for (size_t i = 0; i < len; ++i) printf("%02hhx ", packet[i]);
puts("");
}
注意我在这里也更改了类型:
char
可以签名。如果你想处理原始字节,最好总是使用unsigned char
.int
对于某个尺寸来说可能太小了,请始终使用size_t
,它可以保证在您的平台上容纳任何可能的尺寸。
如果你真的想打印编码字符(二进制数据不太可能),你可以在printf()
中使用%c
,或者使用putchar()
函数,或者fwrite()
整个块到 stdout
.