gpt4 book ai didi

python - 当字符串中存在非ASCII字符时,如何将C字符串(char数组)转换为Python字符串?

转载 作者:太空狗 更新时间:2023-10-29 21:33:11 28 4
gpt4 key购买 nike

我在 C 程序中嵌入了 Python 解释器。假设 C 程序从文件中读取一些字节到一个 char 数组中,并(以某种方式)了解到这些字节表示具有特定编码(例如 ISO 8859-1、Windows-1252 或 UTF-8)的文本。如何将此 char 数组的内容解码为 Python 字符串?

Python 字符串一般应为 unicode 类型——例如,Windows-1252 编码输入中的 0x93 变为 u'\u0201c'.

我曾尝试使用 PyString_Decode,但当字符串中包含非 ASCII 字符时,它总是会失败。这是一个失败的例子:

#include <Python.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
char c_string[] = { (char)0x93, 0 };
PyObject *py_string;

Py_Initialize();

py_string = PyString_Decode(c_string, 1, "windows_1252", "replace");
if (!py_string) {
PyErr_Print();
return 1;
}
return 0;
}

错误信息是UnicodeEncodeError: 'ascii' codec can't encode character u'\u201c' in position 0: ordinal not in range(128),表示ascii即使我们在调用 PyString_Decode 时指定了 windows_1252,也会使用 编码。

以下代码通过使用 PyString_FromString 创建未解码字节的 Python 字符串,然后调用其 decode 方法来解决此问题:

#include <Python.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
char c_string[] = { (char)0x93, 0 };
PyObject *raw, *decoded;

Py_Initialize();

raw = PyString_FromString(c_string);
printf("Undecoded: ");
PyObject_Print(raw, stdout, 0);
printf("\n");
decoded = PyObject_CallMethod(raw, "decode", "s", "windows_1252");
Py_DECREF(raw);
printf("Decoded: ");
PyObject_Print(decoded, stdout, 0);
printf("\n");
return 0;
}

最佳答案

PyString_Decode 这样做:

PyObject *PyString_Decode(const char *s,
Py_ssize_t size,
const char *encoding,
const char *errors)
{
PyObject *v, *str;

str = PyString_FromStringAndSize(s, size);
if (str == NULL)
return NULL;
v = PyString_AsDecodedString(str, encoding, errors);
Py_DECREF(str);
return v;
}

IOW,它基本上完成了您在第二个示例中所做的工作 - 转换为字符串,然后解码该字符串。这里的问题来自 PyString_AsDecodedString,而不是 PyString_AsDecodedObject。 PyString_AsDecodedString 执行 PyString_AsDecodedObject,但随后尝试将生成的 unicode 对象转换为具有默认编码的字符串对象(对您来说,看起来像是 ASCII)。这就是它失败的地方。

我相信您需要执行两次调用 - 但您可以使用 PyString_AsDecodedObject 而不是调用 python“解码”方法。像这样的东西:

#include <Python.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
char c_string[] = { (char)0x93, 0 };
PyObject *py_string, *py_unicode;

Py_Initialize();

py_string = PyString_FromStringAndSize(c_string, 1);
if (!py_string) {
PyErr_Print();
return 1;
}
py_unicode = PyString_AsDecodedObject(py_string, "windows_1252", "replace");
Py_DECREF(py_string);

return 0;
}

我不完全确定 PyString_Decode 以这种方式工作背后的原因是什么。 very old thread on python-dev似乎表明它与链接输出有关,但由于 Python 方法不同,我不确定这是否仍然相关。

关于python - 当字符串中存在非ASCII字符时,如何将C字符串(char数组)转换为Python字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/213628/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com