【问题标题】:Handling UTF-8 in C++在 C++ 中处理 UTF-8
【发布时间】:2012-01-20 17:52:58
【问题描述】:

为了确定 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 等)?
  • Linux,实际上。如果它也可以在 Windows 上运行,那也是一种奖励。
  • 您的语言环境是否设置为 UTF-8 编码?
  • 不一定遵循。无论如何,它适用于普通的stringcincout,而不适用于这里的w... 版本,我怀疑他们想要 UTF-32(或 16?)。
  • 我之前关于该主题的一些问题:#1#2#3

标签: c++ linux stl utf-8 wstring


【解决方案1】:

语言本身与 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 Conversion Helpers(在 MSDN 上,根据 Apache 许可证,版本 2.0 提供)。

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

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

【讨论】:

  • 那么当我想制作一个在两个系统上都将所有内容都视为 UTF-8 的语言编译器/解释器时,您建议我应该怎么做?
  • 好吧,没有简单的答案和“终极”解决方案。这取决于您使用的编译器、IDE 和 API。我建议您使用一些跨平台的应用程序框架,最好是诺基亚的 Qt - qt.nokia.com。它对于开源项目甚至商业项目都是完全免费的——如果您确保遵守 GNU 通用公共许可证 (LGPL)。
【解决方案2】:

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

【讨论】:

  • 是的!与其他一些答案相反,在 Linux 上使用 wchar_t 是完全可以的。不过,您绝对必须使用正确的语言环境。
【解决方案3】:

不要在 Linux 上使用 wstring。

std::wstring VS std::string

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

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

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

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

【讨论】:

  • +1 :看看这个答案。我确定它链接到您的问题的答案。
  • 在 UTF-8 上的 boost::spirit cmets 中,他们总是在谈论使用 wchar_t
  • @Scán:我猜他们一直使用wchar_t 作为代码点,用于将UTF8 转换为任何内容。不过,wchar_t 对于 UTF8 本身来说并不是一个好字符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2011-11-07
  • 2012-08-01
  • 2011-01-22
  • 2011-02-23
  • 2010-09-21
  • 1970-01-01
相关资源
最近更新 更多