如何在 C 中大写/小写 UTF-8 字符?

新手上路,请多包涵

假设我有一个 UTF-8 编码的 std::string 包含以下内容:

óó

我想将其转换为以下内容:

ÓÓ

理想情况下,我希望我使用的大写/小写方法在所有 UTF-8 中都是通用的。如果这甚至可能的话。

字符串中的原始字节序列是 0xc3b3c3b3 (每个字符两个字节,以及 ó 的两个实例),我希望输出为 0xc393c393Ó 的两个实例。 StackOverflow 上有 一些示例,但它们使用宽字符串, 其他答案 说您不应该将宽字符串用于 UTF-8。看起来这个问题可能非常“棘手”,因为输出可能取决于用户的语言环境。

我原本希望只使用 std::toupper() 之类的东西,但我真的不清楚它的用法,因为我似乎不只是一次转换一个字符,而是一个完整的字符串。另外,我放在一起的这个 Ideone 示例 似乎表明 toupper() of 0xc3b3 只是 0xc3b3 ,这是一个意想不到的结果。调用 setlocale 到 UTF-8 或 ISO8859-1 似乎不会改变结果。

如果您能阐明我做错了什么或为什么我的问题/前提有问题,我会很乐意提供一些指导!

原文由 aardvarkk 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 911
2 个回答

在 C++ 中没有进行 Unicode 大小写转换的标准方法。有些方法适用于 某些 C++ 实现,但标准并不要求它们这样做。

如果您想要保证 Unicode 大小写转换,您将需要使用 ICU 或 Boost.Locale 之类的库(又名:ICU 具有更类似于 C++ 的界面)。

原文由 Nicol Bolas 发布,翻译遵循 CC BY-SA 3.0 许可协议

StackOverflow 上有一些示例,但它们使用宽字符串,其他答案说您不应该将宽字符串用于 UTF-8。

(utf8everywhere) 中的文章和答案适用于 Windows。 C++ 标准要求 wchar_t 足够宽以容纳所有支持的代码单元(32 位宽),但与 UTF-8 完美兼容。在 Windows 上, wchar_t 是 UTF-16,但如果你在 Windows 上,你会遇到更多的问题,而不仅仅是我们要诚实(即他们可怕的 API)。

看起来这个问题可能非常“棘手”,因为输出可能取决于用户的语言环境。

并不真地。在代码中设置语言环境。例如 sort 如果您没有在 shell 内设置语言环境,则某些程序无法正常工作,因此用户有责任。

我原本希望只使用 std::toupper() 之类的东西,但我真的不清楚它的用法,因为我似乎不只是一次转换一个字符,而是一个完整的字符串。

代码示例使用迭代器。如果您不想转换每个字符,请不要。

另外,我整理的这个 Ideone 示例似乎表明 0xc3b3 的 toupper() 只是 0xc3b3,这是一个意想不到的结果。将 setlocale 调用为 UTF-8 或 ISO8859-1 似乎不会改变结果。

你有未定义的行为。 unsigned char 的范围是255 0xc3b3 方式超过了。

如果您能阐明我做错了什么或为什么我的问题/前提有问题,我会很乐意提供一些指导!

这个例子工作得很好:

 #include <iostream>
#include <string>
#include <locale>

int main()
{
    std::setlocale(LC_CTYPE, "en_US.UTF-8"); // the locale will be the UTF-8 enabled English

    std::wstring str = L"óó";

    std::wcout << str << std::endl;

    for (std::wstring::iterator it = str.begin(); it != str.end(); ++it)
        *it = towupper(*it);

    std::wcout << str << std::endl;
}

输出: ÓÓ

原文由 user6262916 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题