如何构造unpack c null终止字符串?
我使用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"
。
我怎样才能做到这一点?
打开包装后你可以做一个:
name = name.split('\0', 1)[0]
或者你可以使用ctypes
模块:
name = ctypes.create_string_buffer(name).value
只需将子字符串放到第一个\0
:
prot,id,name = struct.unpack("@Bi32s") name= name[:name.index("\0")]
如果字符串中没有\0
,则它具有检查和失败(抛出ValueError
)的特殊性。
解包后用空字符( '\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'
替代使用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'
如何使用rstrip删除填充?
prot,id,name = struct.unpack("@Bi32s") name = name.rstrip(b'\0')
这也将允许您使用所有32个字节来存储名称而不使用零终止符。 但是,这确实依赖于将所有填充字节设置为零。