【问题标题】:C++ ctype facet for UTF-8 in mingwmingw 中 UTF-8 的 C++ ctype facet
【发布时间】:2010-11-24 03:47:20
【问题描述】:

在一个项目中,所有内部字符串都保存为 utf-8 编码。该项目已移植到 Linux 和 Windows。现在需要 to_lower 功能。

在 POSIX 操作系统上,我可以使用 std::ctype_byname("ru_RU.UTF-8")。但是对于 g++ (Debian 4.3.4-1),ctype::tolower() 不能识别俄语 UTF-8 字符(拉丁文本小写很好)。

在 Windows 上,当我尝试使用“ru_RU.UTF-8”参数构造 std::ctype_byname 时,mingw 的标准库抛出异常“std::runtime_error: locale::facet::_S_create_c_locale name not valid”。

如何在 Windows 上为 utf-8 实现/查找 std::ctype?该项目已经依赖于 libiconv(codecvt facet 基于它),但我没有看到用它实现 to_lower 的明显方法。

【问题讨论】:

  • ctype 不能处理多字节编码的原因是它不能修改符号的大小。 utf-8 转换应由不同的接口处理。抱歉,我之前没能收到。
  • 根据我的记忆glibc 为不同的语言环境生成信息。可能是相关机器上没有安装相关的语言环境文件。

标签: c++ utf-8 mingw ctype


【解决方案1】:

如果您只需要西里尔字符的 to_lower,您可以自己编写一个函数。

АБВГДЕЖ UTF8 D0 90 D0 91 D0 92 D0 93 D0 94 D0 95 D0 96 0A
UTF8 D0 B0 D0 B1 D0 B2 D0 B3 D0 B4 D0 B5 D0 B6 0A 中的 абвгдеж 

但不要忘记 UTF8 是多字节编码。

您也可以尝试将字符串从 UTF8 转换为 wchar_t(使用 libiconv)并使用 Windows 特定函数来实现 to_lower。

【讨论】:

    【解决方案2】:

    尝试使用STLport

    以下是如何使用 STLport 读取/写入 utf8 文件的说明。 utf8 是一种编码宽字符的方式。因此,编码管理 C++ 标准库由 codecvt locale facet 处理,它是一部分 属于 ctype 类别。然而 utf8 只描述编码必须如何 执行,它不能用于对字符进行分类,因此信息不足 了解如何生成语言环境的整个 ctype 类别方面 实例。 在 C++ 中,这意味着以下代码将引发异常 创建失败的信号: #包括 // 将抛出 std::runtime_error 异常。 std::locale loc(".utf8"); 出于同样的原因,使用基于的 ctype 构面构建语言环境 UTF8 也是错误的: // 将抛出 std::runtime_error 异常: std::locale loc(locale::classic(), ".utf8", std::locale::ctype); 获取将处理 utf8 编码的语言环境实例的唯一解决方案 是专门表示codecvt方面应该基于utf8 编码: // 如果有必要的平台支持将成功。 locale loc(locale::classic(), new codecvt_byname(".utf8")); 一旦你获得了一个语言环境实例,你可以将它注入到一个文件流中 读/写 utf8 文件: std::fstream fstr("file.utf8"); fstr.imbue(loc); 您还可以直接访问 facet 以执行 utf8 编码/解码操作: typedef std::codecvt codecvt_t; 常量 codecvt_t& 编码 = use_facet(loc); 笔记: 1. 点('.')在utf8前面是必须的。这是一个 POSIX 约定,语言环境 名称具有以下格式: 语言[_country[.encoding]] 例如:'fr_FR' '法语' 'ru_RU.koi8r' 2. utf8编码暂时只支持Windows下。不太常见的 还支持 utf7 编码。

    【讨论】:

    • 所有这些都可以在没有 STLport 的 linux 或 windows 中完成。您的示例中没有 ctype 。您的 codecvt 会将 utf-8 转换为不同的编码(CP???? 或 WCHAR_T),而我的问题是关于 utf-8 作为内部表示。
    【解决方案3】:

    有一些 STL(例如来自 Apache 的 STDCXX)带有多个语言环境。但在其他情况下,语言环境仅取决于系统。

    如果您可以在一个操作系统上使用名称“ru_RU.UTF-8”,这并不意味着其他系统在此语言环境中具有相同的名称。 Debian 和 windows 可能有其他名称,这就是您出现运行时异常的原因。

    您应该先在系统上安装您想要的语言环境。或使用已具有此语言环境的 STL。

    我的美分...

    【讨论】:

    • 我很确定 windows 知道如何处理 utf-8 编码。我什至有代码页号 - 65001。问题是 - 在我的情况下应该使用什么语言环境名称。无论如何,似乎我正在尝试做一件根本错误的事情(请参阅对问题的评论)。
    • 这个页面对你有帮助吗:msdn.microsoft.com/en-us/library/dd373814(VS.85).aspx?
    猜你喜欢
    • 2015-07-25
    • 1970-01-01
    • 2012-08-18
    • 2018-03-05
    • 1970-01-01
    • 2020-01-29
    • 2012-07-21
    • 2013-09-11
    • 2012-08-15
    相关资源
    最近更新 更多