C++ 如何将U32字符串(char32_t)大写为特定区域设置?

C++ 如何将U32字符串(char32_t)大写为特定区域设置?,c++,c++11,unicode,uppercase,ctype,C++,C++11,Unicode,Uppercase,Ctype,在使用Visual Studio 2017的Windows上,我可以使用以下代码将大写字母au32string(基于char32\t): #包括 #包括 #包括 void toUpper(std::u32string&u32str,std::string localeStr) { std::locale(localeStr); 对于(无符号i=0;i我找到了一个解决方案: 我现在将std::u32string与utf8编码一起使用std::string。 从std::u32string到std:

在使用Visual Studio 2017的Windows上,我可以使用以下代码将大写字母a
u32string
(基于
char32\t
):

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

对于(无符号i=0;i我找到了一个解决方案:

我现在将
std::u32string
utf8
编码一起使用
std::string
。 从
std::u32string
std::string
(utf8)的转换可以通过
utf8 cpp
完成:

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

voidtoupper(std::string&str,std::stringlocalestr)
{
//unicode到宽字符串转换器
std::wstring_转换器;
//转换为wstring(因为u32string的所有平台上都没有实现std::toupper)
std::wstring-wide=转换器从字节(str);
std::locale;
尝试
{
locale=std::locale(localeStr);
}
捕获(const std::exception&)
{

我找到了一个解决方案:

我现在将
std::u32string
utf8
编码一起使用
std::string
。 从
std::u32string
std::string
(utf8)的转换可以通过
utf8 cpp
完成:

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

voidtoupper(std::string&str,std::stringlocalestr)
{
//unicode到宽字符串转换器
std::wstring_转换器;
//转换为wstring(因为u32string的所有平台上都没有实现std::toupper)
std::wstring-wide=转换器从字节(str);
std::locale;
尝试
{
locale=std::locale(localeStr);
}
捕获(const std::exception&)
{

std::cerr感觉您缺少了一个
#include
。如果没有,很难说。我不认为我缺少了一个头文件。我已经在示例中添加了include。也许您的编译器的RTL根本没有实现
ctype
?顺便说一句,这似乎是您应该使用的
std::transform()
代替手动循环,例如:
std::locale loc(localeStr);std::transform(u32str.begin(),u32str.end(),u32str.begin(),[&loc](char32_t c)->char32_t{return std::toupper(c,loc);};
我想是这样。有更好的(便携的)吗方法?关于这一点:似乎不支持
ctype
感觉你缺少了一个
#include
。如果没有一个,很难说。我不认为我遗漏了一个头文件。我已经在示例中添加了include。也许你的编译器的RTL根本没有实现
ctype
。顺便说一句,这看起来像是som您应该使用
std::transform()
来代替手动循环,例如:
std::locale loc(localeStr);std::transform(u32str.begin(),u32str.end(),u32str.begin(),[&loc](char32_t c)->char32_t{return std::toupper(c,loc)};
我想是的。有更好的(便携的)吗这样做的方法?关于这一点:似乎不支持
ctype
#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);
}
/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);
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);
}