首页 > 解决方案 > 如何在缓冲区中打印数据,而不考虑到给定长度之间的零

问题描述

我写了一个简单的程序来读取一个数据包直到第 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
$1 = 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 中,信息与我的输入不同。

标签: cprintingpacket

解决方案


C 中的字符串定义为以'\0'(0 字节)结尾的字符序列,%s转换说明符printf()is 用于strings。因此,您的问题的解决方案是做其他事情来打印二进制字节。例如,如果您想打印它们的十六进制值,您可以像这样更改您的打印功能:

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可保证在您的平台上保持任何尺寸的产品。

如果你真的想打印编码字符(二进制数据不太可能),你可以使用%cin printf(),或者使用putchar()函数,或者fwrite()整个块 to stdout


推荐阅读