std::string.c_str()使用哪种编码?

36
我正在尝试将C++中的 std::string 转换为UTF-8或 std::wstring,而不会丢失信息(考虑包含非ASCII字符的字符串)。根据http://forums.sun.com/thread.jspa?threadID=486770&forumID=31的说法:如果 std::string 包含非ASCII字符,则必须提供一个函数将其从您的编码转换为UTF-8。 那么,std::string.c_str() 使用什么编码?如何以跨平台方式将其转换为UTF-8或 std::wstring
2个回答

52

std::string 本身不使用编码 - 它将返回您放入其中的字节。例如,这些字节可能使用 ISO-8859-1 编码... 或者任何其他编码:关于编码的信息只是不存在的 - 您必须知道这些字节来自何处!


1
那么本质上,如果我事先不知道std::string的编码方式,就没有办法将其转换吗?我问这个问题是因为我正在编写一个API函数,它需要输入一个std::string。我想文档需要告诉用户传递什么格式的字符串。 - Gili
3
@Gili,正确的:你无法可靠地将未知编码的字节序列转换为UTF-8(或其他任何东西;-)。我建议您要求调用者提供UTF-8数据--大多数其他编码不允许编码每个可能的Unicode字符串。正如@Naaff所说,ASCII是UTF-8的一种特殊情况(以及ISO-8859-*和许多其他编码),因此如果这是您的情况,就没有问题(在文档中加入脚注提醒用户这一事实可能会节省他们的担忧;-)。 - Alex Martelli
1
ISO-8859系列编码并不是UTF-8的“特殊情况”。它们只是不同的单字节编码。 - n0rd
2
ASCII字符串也是UTF-8字符串和ISO-8859-1字符串等:这就是为什么括号出现在UTF-8后面而不是紧挨着ASCII的原因;-)。 - Alex Martelli
2
这份文档支持此说法:请注意,该类独立于所使用的编码处理字节:如果用于处理多字节或可变长度字符序列(例如UTF-8),则该类的所有成员(如长度或大小)以及其迭代器仍将按字节运作(而非实际编码字符)。http://www.cplusplus.com/reference/string/string/ - Ohad Schneider
我想举一个例子来说明“你必须知道字节的来源!”。例如,如果您正在使用中文Windows系统,并在Visual Studio中使用一些中文字符初始化一个string,那么编码是基于代码页的,默认情况下是与语言/区域设置相关的GB2312编码。 - Rick

7

std::string 包含任意字节序列,因此编码由您决定。您必须知道它是如何编码的。但是,如果您不知道它是其他编码方式,则可能只是 ASCII 编码。在这种情况下,它已经兼容 UTF-8。


21
“我见过‘可能只是……’导致了许多字符编码错误。”我建议在涉及字符编码时,不要猜测:无论是输入还是输出,都一定要非常明确。如果没有指定字符集,则每次都需添加一个额外的参数/返回值来指示编码。 - MtnViewMark

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