在C++中处理UTF-8

12

为了确定C++是否适合我的项目,我想测试其UTF-8功能。根据参考资料,我构建了这个示例:

#include <string>
#include <iostream>

using namespace std;

int main() {
    wstring str;
    while(getline(wcin, str)) {
        wcout << str << endl;
        if(str.empty()) break;
    }

    return 0;
}

但是当我输入一个UTF-8字符时,它会表现不正常:

$ > ./utf8 
Hello
Hello
für
f
$ >

它不仅没有打印出 ü,而且立即退出。 gdb 告诉我没有崩溃,只是正常退出,但我很难相信。


你的目标平台是哪个(Windows、Linux等)? - M.Babcock
实际上是Linux。如果它也能在Windows上运行,那就是一个额外的好处。 - Lanbo
2
你的语言环境设置为UTF-8编码了吗? - Daniel Fischer
1
不一定遵循。无论如何,它可以使用普通的stringcincout正常工作,但在这里不适用于w...版本,我怀疑他们想要UTF-32(或16?)。 - Daniel Fischer
1
关于该主题的一些之前的问题:#1, #2, #3 - Kerrek SB
3个回答

10

不要在Linux上使用wstring。

std::wstring VS std::string

看一下第一个答案。我相信它回答了你的问题。

  1. 什么时候应该使用std::wstring而不是std::string?

在Linux上吗?几乎从来不用 (§)。

在Windows上?几乎总是 (§)。


+1:看看这个答案。我相信它链接到了你问题的答案。 - Klaim
boost::spirit关于UTF-8的注释中,他们总是谈论使用wchar_t - Lanbo
@Scán:我猜他们一直使用wchar_t来表示代码点,用于将UTF8与其他编码互相转换。但是,wchar_t本身并不适合表示UTF8字符。 - Mooing Duck

10

编程语言本身与Unicode或其他字符编码无关,而是与操作系统相关。Windows为了支持Unicode而使用UTF16,这意味着需要使用宽字符(16位宽字符)- wchar_t或std:wstring。每个操作字符串的Win Api函数都需要宽字符输入。

但基于Unix的系统,例如Mac OS X或Linux使用UTF8。当然,这只是处理数组中的字节的方式问题,因此可以在通用C数组或std:string容器中存储UTF16字符串。这就是为什么跨平台代码中没有看到任何wstrings,而所有字符串都被视为UTF8并在必要时重新编码为UTF16(在Windows上)。

您有更多选项来处理这些有点令人困惑的东西。我个人使用上述严格在所有应用程序中使用UTF8编码的方法,在与Windows Api交互时重新编码字符串,并在Mac OS X上直接使用它们。为了在Windows上重新编码,我使用了非常好的转换助手:

C++ UTF-8 Conversion Helpers(在MSDN上,可在Apache许可证版本2.0下获得)。

您还可以使用跨平台Qt字符串,该字符串定义了从UTF8到/从UTF16和其他编码(ANSI,Latin ...)的转换函数。

因此,上述答案-在Unix上始终使用UTF8(std:string,char),在Windows上使用UTF16(std:wstring,wchar_t)是正确的。


那么,当我想要制作一个在两个系统上都将所有内容视为UTF-8的语言编译器/解释器时,您建议我应该做什么? - Lanbo
1
好的,关于这个编程问题并没有简单的答案或者“最终”解决方案。它取决于您使用了哪些编译器、集成开发环境和应用程序接口。我建议您使用一些跨平台的应用程序框架,最好是诺基亚的Qt框架- http://qt.nokia.com。 如果您确保符合GNU通用公共许可证(LGPL)规定的话,它完全免费适用于开源项目甚至商业项目。 - vitakot

4

记住,在主程序启动时,“C”区域设置被选择为默认值。如果您处理的是utf-8,则可能不希望这样。 调用setlocale(LC_CTYPE, "")关闭此默认值,然后您将得到环境中定义的任何值(可能是utf-8本地化)。


1
是的!与其他答案相反,在Linux上使用wchar_t是完全可以的。但是你必须使用正确的区域设置。 - n. m.

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