简体   繁体   English

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

[英]How to struct unpack c null terminated string?

I used tcp to send a data to python server. 我使用tcp将数据发送到python服务器。 The data is like: 数据如下:

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

Look at the name field, it is a null terminated string max size is 32. Now I use strcpy . 查看name字段,它是一个以null结尾的字符串,最大大小为32.现在我使用strcpy

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

Now I unpack it using python. 现在我用python解压缩它。

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

Now the len(name) is 32. But I need get the string of "abc" when the length is 3. 现在len(name)是32.但是当长度为3时我需要获得字符串"abc"

How can I do that? 我怎样才能做到这一点?

After the unpacking you can just do a: 打开包装后你可以做一个:

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

Alternatively you could use the ctypes module: 或者你可以使用ctypes模块:

name = ctypes.create_string_buffer(name).value

Partition it with null character ( '\\0' ) after the unpack: 解包后用空字符( '\\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'

Alternative using ctypes : 替代使用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'

Simply get the substring up to the first \\0 : 只需将子字符串放到第一个\\0

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

This has the particularity that it will check and fail (throw ValueError ) if no \\0 appears inside the string. 如果字符串中没有\\0 ,则它具有检查和失败(抛出ValueError )的特殊性。

How about using rstrip to remove the padding? 如何使用rstrip删除填充?

prot,id,name = struct.unpack("@Bi32s")
name = name.rstrip(b'\0')

This will also let you use all 32 bytes to store the name without a zero terminator. 这也允许您使用所有32个字节来存储名称而不使用零终止符。 However, this does rely on ALL padding bytes being set to zero. 但是,这确实依赖于将所有填充字节设置为零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM