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告诉我没有崩溃,而是正常退出,但我觉得很难相信。

4

3 回答 3

10

不要在 Linux 上使用 wstring。

std::wstring VS std::string

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

  1. 我什么时候应该在 std::string 上使用 std::wstring?

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

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

于 2011-12-14T23:55:38.053 回答
10

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

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

你有更多的选择来处理这个有点混乱的东西。我个人按照上面提到的那样做——通过在所有应用程序中严格使用 UTF8 编码,在与 Windows Api 交互时重新编码字符串并直接在 Mac OS X 上使用它们。对于 win 重新编码,我使用了很好的转换助手:

C++ UTF-8 转换助手(在 MSDN 上,在 Apache 许可证下可用,版本 2.0)。

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

所以上面的答案 - 在 unix 上总是使用 UTF8 (std::string, char),在 Windows 上 UTF16 (std::wstring, wchar_t) 是正确的。

于 2011-12-15T00:42:55.647 回答
4

请记住,在主程序启动时,默认选择“C”语言环境。如果你处理 utf-8,你可能不想要这个。调用setlocale(LC_CTYPE, "")会关闭此默认设置,您将获得环境中定义的任何内容(可能是 utf-8 语言环境)。

于 2012-02-26T11:38:44.257 回答