Python转C++字符编码

3

我有一个C++程序,使用Python C/API调用Python脚本获取数据库信息,但接收到的数据编码方式不正确。这是在法国,因此我的数据具有重音符号和其他非英语字符。

在将sys.defaultencoding设置为“utf-8”的Python终端中,例如:

    >>> robin = 'testé'
    >>> robin
    'test\x82'
    >>> print robin
    testé
    >>> str(robin)
    'test\x82'

如果我调用:
    PyString_AsString(PyObject_Repr(PyObject_GetAttrString(/*PyObject of my Py_Init*/, "robin")));

我得到了一个char*,内容为:test\x82

从中创建一个stringwstring会得到相同的结果。

我希望能够创建一个字符串,例如"testé",我猜想首先需要正确地在Python终端中输出该变量:

    >>> robin = 'testé'
    >>> robin
    'testé'

我尝试使用encode() decode()、sys.setdefaultencoding、sys.stdout.encoding,甚至从Django中使用一些force_text和force_bytes。似乎没有任何方法可以让我得到一个包含实际字符的标准C++字符串。非常感谢任何帮助。
FYI - Python 2.7、Windows 8 x64、VS2012和C++9
编辑以回答评论:
    >>> import sys
    >>> reload(sys)
    <module 'sys' (built-in)>
    >>> sys.setdefaultencoding('utf-8')
    >>> sys.getdefaultencoding()
    'utf-8'
    >>> robin = 'testé'
    >>> robin
    'test\x82'
    >>> print robin
    testé

我只希望“print”所做的能正确地显示信息...

我不确定 VC,但在 Linux 上我使用 CodeBlocks 和 wxWidgets,转换非常安全(我的意思是没有错误)。 - itsols
你是在Python中声明这个robin变量,并将其从C语言获取以使用C输出,对吗?在我看来,问题可能是正确的UTF-8编码应该是\xc2\x82而不是\x82,这可能是输出问题的原因。 - Paulo Bu
sys.stdout.encoding 是什么? - Janne Karila
@PauloBu 我意识到了。但无论是UTF8、UTF16、ascii还是其他编码方式,我仍然没有得到正确的数据。请看我的编辑。 - Robin Eisenberg
2个回答

1
这并不像看起来那么简单,我错了,utf-8中的acute e是c3 a9。在控制台上使用Python解释器处理编码很难,有几件事情你必须做对。
首先,你需要检查控制台的默认代码页(编码)。你可以通过发出chcp命令来检查。我的显示为437,但这基本取决于你的Windows安装。 Latin-1的代码页为28591,而UTF-8的代码页为65001。奇怪的是,当控制台的代码页为65001时,使用Python解释器似乎很复杂,因为在Python的编码库中还没有声明它是utf-8的同义词。
我的观点是,你必须正确理解。如果你的控制台处于代码页X中,你输入到Python解释器的内容将被编码为X,并且你将以X能够处理字节的方式看到输出。
我建议您在Python中使用Unicode而不是硬编码字符串,并使用转义字节而不是字符。例如,您可以这样声明robin:

我建议您在Python中使用Unicode而不是硬编码字符串,并使用转义字节而不是字符。例如,您可以这样声明robin:

robin = u'test\xe9'

U+00E9是é的代码。之后,robin是Unicode,可以像这样编码成任何你想要的编码:robin.encode('utf-8')。这样你就可以控制变量以便在任何可能的输出情况下对其进行编码。

总结一下:

  1. 确定您的控制台编码
  2. 根据此编码编码robin变量
  3. 控制台应该正确输出它

希望这有所帮助!


3
需要注意的另一件事是,在Windows GUI应用程序中,默认的代码页可以与控制台窗口的默认代码页不同。(关于C++应用程序是控制台还是GUI应用程序的问题不太清楚。) - Janne Karila
是的,这是另一个观点。我不确定。好观点! - Paulo Bu

0

你调用了PyObject_Repr,它与Python中的repr(robin)相同,并生成文字字面量\x82。在你的调用链中省略它。


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