当字符串中包含非ASCII字符时,如何将C字符串(字符数组)转换为Python字符串?

当字符串中包含非ASCII字符时,如何将C字符串(字符数组)转换为Python字符串?,python,c,character-encoding,embedding,Python,C,Character Encoding,Embedding,我在C程序中嵌入了Python解释器。假设C程序将文件中的一些字节读入字符数组,并(以某种方式)了解到这些字节表示具有特定编码的文本(例如,ISO 8859-1、Windows-1252或UTF-8)。如何将这个字符数组的内容解码为Python字符串 Python字符串通常应为unicode类型-例如,Windows-1252编码输入中的0x93成为u'\u0201c' 我曾尝试使用PyString\u Decode,但当字符串中有非ASCII字符时,它总是失败。以下是一个失败的示例: #inc

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

Python字符串通常应为
unicode
类型-例如,Windows-1252编码输入中的
0x93
成为
u'\u0201c'

我曾尝试使用
PyString\u 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;
}

您不想将字符串解码为Unicode表示,只想将其视为字节数组,对吗

只需使用
PyString\u FromString

char *cstring;
PyObject *pystring = PyString_FromString(cstring);
就这些。现在您有了一个Python
str()
对象。请参见此处的文档:


我对如何指定“str”或“unicode”有点困惑。如果您使用非ASCII字符,它们会非常不同。如果您想解码C字符串您确切地知道它在哪个字符集中,那么是的,
PyString\u DecodeString
是一个很好的开始。

尝试调用“
If(!py\u string)
”子句。也许python异常会为您提供更多信息。

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

我相信您需要执行两个调用—但是您可以使用PyString_AsDecodedObject,而不是调用python的“decode”方法。比如:

#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;
}
#包括
#包括
int main(int argc,char*argv[])
{
字符c_字符串[]={(字符)0x93,0};
PyObject*py_字符串,*py_unicode;
Py_初始化();
py_string=PyString_FromStringAndSize(c_string,1);
如果(!py_字符串){
PyErr_Print();
返回1;
}
py_unicode=PyString_AsDecodedObject(py_string,“windows_1252”,“replace”);
Py_DECREF(Py_字符串);
返回0;
}

我不完全确定PyString_解码以这种方式工作的原因是什么。A似乎表明它与链接输出有关,但由于Python方法不这样做,我不确定这是否仍然相关。

对于挑剔,C字符串是char[],而不是char*,在引用值时,这并不重要。无论如何,数组都是作为指向函数的指针传递的。我想对其进行实际解码,因此,无论最终使用字符串的Python代码是什么,都不需要知道它最初是如何编码的(在C程序的输入中)。谢谢你指出我不清楚;我已经编辑了我的问题。谢谢,我编辑了,并将信息合并到了问题中。没问题。如果建议有帮助,我将非常感谢您的支持。:-)用于蟒蛇3
#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;
}