c++ - 如何将具有特定语言环境的 u32string (char32_t) 大写?

标签 c++ c++11 unicode uppercase ctype

在带有 Visual Studio 2017 的 Windows 上,我可以使用以下代码将 u32string(基于 char32_t)大写:

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

void toUpper(std::u32string& u32str, std::string localeStr)
{
    std::locale locale(localeStr);

    for (unsigned i = 0; i<u32str.size(); ++i)
        u32str[i] = std::toupper(u32str[i], locale);
}

同样的事情不适用于 macOS 和 XCode。 我收到这样的错误:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__locale:795:44: error: implicit instantiation of undefined template 'std::__1::ctype<char32_t>'
return use_facet<ctype<_CharT> >(__loc).toupper(__c);

是否有一种可移植的方式来执行此操作?

最佳答案

我找到了一个解决方案:

我现在不使用 std::u32string,而是使用 std::stringutf8 编码。 从 std::u32stringstd::string (utf8) 的转换可以通过 utf8-cpp 完成:http://utfcpp.sourceforge.net/

需要将 utf8 字符串转换为 std::wstring(因为 std::toupper 并未在所有平台上实现 std::u32string).

void toUpper(std::string& str, std::string localeStr)
{
    //unicode to wide string converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

    //convert to wstring (because std::toupper is not implemented on all platforms for u32string)
    std::wstring wide = converter.from_bytes(str);

    std::locale locale;

    try
    {
        locale = std::locale(localeStr);
    }
    catch(const std::exception&)
    {
        std::cerr << "locale not supported by system: " << localeStr << " (" << getLocaleByLanguage(localeStr) << ")" << std::endl;
    }

    auto& f = std::use_facet<std::ctype<wchar_t>>(locale);

    f.toupper(&wide[0], &wide[0] + wide.size());

    //convert back
    str = converter.to_bytes(wide);
}

注意:

  • 在 Windows 上 localeStr 必须是这样的:en, de, fr, ...
  • 在其他系统上:localeStr 必须是 de_DE, fr_FR, en_US, ...

关于c++ - 如何将具有特定语言环境的 u32string (char32_t) 大写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45578392/

相关文章:

c - 制作宽字 rune 件

c++ - 如何使用树 C++ 评估 bool 语句

c++ - 初始化指向类实例的智能指针并访问其方法

c++ - 使用 nullptr 终止迭代器

c++ - boost::log 在 channel 记录器中设置 "Channel"属性

java - 有没有办法输入一个unicode值并输出其各自的字符?

python-2.7 - 已经转换为 Unicode 的单词也被认为是新的用户输入,并被一次又一次地转换

c++ - std::thread 线程在对象中分离出来,它什么时候终止?

c++ - 类对象 vector 上的 sort() 给出段错误

c++ - 工具提示中的 Qt WIdget