如何构造unpack c空终止字符串?

2024-05-19 21:14:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用tcp向python服务器发送数据。数据如下:

struct protocol
{
    unsigned char prot;
    int id;
    char name[32];
}

看看name字段,它是一个以空结尾的字符串,最大大小为32。现在我使用strcpy

protocol p;
memset(&p, 0, sizeof(p));
strcpy(name, "abc");

现在我用python解压它。

prot,id,name = struct.unpack("@Bi32s")

现在len(name)是32。但是当长度是3时,我需要得到"abc"的字符串。

我该怎么做?


Tags: 数据字符串nameid结尾protocolstructtcp
3条回答

打开包装后,您可以执行以下操作:

name = name.split('\0', 1)[0]

或者,您可以使用ctypes模块:

name = ctypes.create_string_buffer(name).value

解包后用空字符('\0')对其进行分区:

>>> prot, id, name = struct.unpack('@Bi32s', b'\0\0\0\0\0\0\0\0abc' + b'\0' * 29)
>>> name, _, _ = name.partition('\0')
>>> name
'abc'

替代使用^{}

>>> from ctypes import *
>>>
>>> class Protocol(Structure):
...     _fields_ = [("prot", c_char),
...                 ("id", c_int),
...                 ('name', c_char * 32)]
...
>>> # sock.recv_into(buf) in real program
... buf = create_string_buffer(b'\0\0\0\0\0\0\0\0abc' + b'\0' * 29)
>>> p = cast(buf, POINTER(Protocol))
>>> p[0].name
'abc'

只需将子串放到第一个\0

prot,id,name = struct.unpack("@Bi32s")
name= name[:name.index("\0")]

它有一个特殊性,即如果字符串中没有出现\0,它将检查并失败(抛出ValueError)。

相关问题 更多 >