如何在Python中生成一个十六进制转义字符串以便在C++中使用?

4

我正在尝试为使用MessagePack的库创建合成单元测试。我希望在Python中创建十六进制转义的二进制字符串,以便将其嵌入C++源代码中。我像这样创建一个:

In [6]: umsgpack.packb([0, 0, 'dummy_void_zeroarg', []])
Out[6]: '\x94\x00\x00\xc4\x12dummy_void_zeroarg\x90'

然而,似乎生成的十六进制字符串几乎可以在C++中使用,但不完全符合要求:

error: hex escape sequence out of range
        "\x94\x00\x00\xc4\x12dummy_void_zeroarg\x90";
                         ^~~~~

原因是编译器会将\x12d解析为单个值。是否有一种方法可以将上面的十六进制字符串转换为Python中不包含字母(即仅包含\x项)的字符串呢?

2个回答

1

你必须手动完成:

"'{}'".format(''.join(['\\x{:02x}'.format(ord(c)) for c in message]))

打印结果或将其写入文件:

>>> print "'{}'".format(''.join(['\\x{:02x}'.format(ord(c)) for c in message]))
'\x94\x00\x00\xc4\x12\x64\x75\x6d\x6d\x79\x5f\x76\x6f\x69\x64\x5f\x7a\x65\x72\x6f\x61\x72\x67\x90'

1

您可能希望使用初始化列表和char字面值,如下所示:

char abc[] = {'\x41', 'B', 'C', 0};

因此,用于生成初始化器的相关Python代码如下:

print("{{{}, 0}}".format(', '.join(map(repr, source_string))))

所以针对您的字符串,我得到如下内容:
{'\x94', '\x00', '\x00', 'Ä', '\x12', 'd', 'u', 'm', 'm', 'y', '_', 'v', 'o', 'i', 'd', '_', 'z', 'e', 'r', 'o', 'a', 'r', 'g', '\x90', 0}

@MartijnPieters 哎呀,那是来自 repr 的,我错过了那个。有一个简单的修复方法,但现在感觉有点像 hacky。 - TNW
@MartijnPieters 我不敢假设每个字符调用map是一个好的性能选择。CPython是否内联repr调用呢?我预计对于更大的字符串会很慢。至于"%r",遗憾的是它会遇到相同的引号问题,但还是谢谢你提供这个信息 - 我之前并不知道。至于str.format() - 是的,我会进行替换。 - TNW
是的,使用带有repr的循环是O(n)的方法。但是在源字符串上使用str.join()也是如此。然而,这两个循环都完全在C中执行。 - Martijn Pieters
从复杂度的角度来看,是的。我是在考虑堆栈帧/调用帧(C语言习惯)。我需要运行timeit并查看。 - TNW
除非你主要生成这样的字符串,否则差异并不重要,因为你正在运行Python代码来生成文本。这可能不需要优化到这个程度,甚至没有足够的差异来证明需要努力弄清楚这一点,那么在未来,当你维护代码时,再次考虑为什么做出这些选择。 - Martijn Pieters
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接