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

tjh*_*ack 10 c python

我使用tcp将数据发送到python服务器.数据如下:

struct protocol
{
    unsigned char prot;
    int id;
    char name[32];
}
Run Code Online (Sandbox Code Playgroud)

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

protocol p;
memset(&p, 0, sizeof(p));
strcpy(name, "abc");
Run Code Online (Sandbox Code Playgroud)

现在我用python解压缩它.

prot,id,name = struct.unpack("@Bi32s")
Run Code Online (Sandbox Code Playgroud)

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

我怎样才能做到这一点?

mar*_*eau 9

打开包装后你可以做一个:

name = name.split('\0', 1)[0]
Run Code Online (Sandbox Code Playgroud)

或者你可以使用该ctypes模块:

name = ctypes.create_string_buffer(name).value
Run Code Online (Sandbox Code Playgroud)

  • 在我的例子中,我不得不使用二进制字符串进行拆分,即``mystr = mybuff.split(b'\ 0',1)[0]``.否则我得到:``TypeError:需要一个类似字节的对象,而不是'str'``. (2认同)

fal*_*tru 3

'\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'
Run Code Online (Sandbox Code Playgroud)

替代使用ctypes

>>> 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'
Run Code Online (Sandbox Code Playgroud)