如何将具有特定语言环境的 u32string (char32_t) 大写?
How to uppercase a u32string (char32_t) with a specific locale?
On Windows with Visual Studio 2017 我可以使用以下代码将 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::string
和 utf8
编码,而不是使用 std::u32string
。
从 std::u32string
到 std::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
、...
On Windows with Visual Studio 2017 我可以使用以下代码将 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::string
和 utf8
编码,而不是使用 std::u32string
。
从 std::u32string
到 std::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
、...