如何用特定的语言环境大写u32string(char32_t)?

时间:2017-08-08 21:34:53

标签: 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);

有可行的方法吗?

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案:

而不是使用std::u32string我现在使用std::string进行utf8编码。 从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必须是这样的:endefr,...
  • 在其他系统上:localeStr必须为de_DEfr_FRen_US,...