如何在C++中将西里尔字母从大写转换为小写或反之亦然?

bkkx9g8r  于 2023-03-25  发布在  其他
关注(0)|答案(2)|浏览(174)
#include <iostream>
#include <locale>

int main() {
    char upper_cyrillic = 'А';
    std::locale loc("ru_RU.UTF-8");
    char lower_cyrillic = std::tolower(upper_cyrillic, loc);
    std::cout << lower_cyrillic << std::endl;
    return 0;
}

我尝试了ChatGPT提供的所有选项,但它们都不起作用。

jhdbpxl9

jhdbpxl91#

假设一个实现知道西里尔文,并且能够识别该语言环境的名称,那么您就相当接近于工作代码了。

#include <iostream>
#include <locale>

int main() {
    std::locale ru{"ru_RU.UTF-8"};

    std::wcout.imbue(ru);
    std::locale::global(ru);

    auto& facet = std::use_facet<std::ctype<wchar_t>>(ru);

    std::wstring input = L"Привет, как дела?";

    facet.toupper(input.data(), input.data() + input.size());
    std::wcout << input << L"\n";

    facet.tolower(input.data(), input.data() + input.size());
    std::wcout << input << L"\n";
}

结果:

ПРИВЕТ, КАК ДЕЛА?
привет, как дела?

Test on Coliru
作为旁注,是的,它可能看起来像设置全局区域设置应该是不必要的(我更希望它是),但如果没有它,它会将结果翻译为英语字符,所以(例如)'Д'变成'D'
就UTF-8编码而言,您通常会通过将UT 8 -8转换为UTF-16或UTF-32来处理,内部操作,然后(如果需要)转换回UTF-8以进行输出,类似于以下内容:

#include <iostream>
#include <locale>
#include <codecvt>

int main() {
    std::locale ru{"ru_RU.UTF-8"};

    std::cout.imbue(ru);
    std::locale::global(ru);

    auto& facet = std::use_facet<std::ctype<wchar_t>>(ru);

    std::string input = "\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1"
        "\x82\x2c\x20\xd0\xba\xd0\xb0\xd0\xba\x20\xd0\xb4\xd0\xb5\xd0"
        "\xbb\xd0\xb0\x3f";

    std::cout << "Mixed case: " << input << "\n";

    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring buffer = converter.from_bytes(input);
    
    facet.toupper(buffer.data(), buffer.data() + buffer.size());
   
    std::string upper = converter.to_bytes(buffer);

    std::cout << "Upper case: " << upper << "\n";

    facet.tolower(buffer.data(), buffer.data() + buffer.size());

    std::string lower = converter.to_bytes(buffer);

    std::cout << "Lower case: " << lower << "\n";
}

结果:

Mixed case: Привет, как дела?
Upper case: ПРИВЕТ, КАК ДЕЛА?
Lower case: привет, как дела?

Test on Coliru
在Ubuntu 22.04上用gcc 11.3.0测试。

dced5bon

dced5bon2#

char只用于“普通”字符。如果需要更多,请研究宽字符,unicode,UTF-8,UTF-16和UTF-32。
您可以使用宽字符,例如:

#include <iostream>
#include <locale>
int main() {
    std::setlocale(LC_ALL, "");
    wchar_t upper_cyrillic = L'П';
    wchar_t lower_cyrillic = std::towlower(upper_cyrillic);
    std::wcout << lower_cyrillic << std::endl;
}

相关问题