如何在c++中将unicode字符转换为大写

How to convert unicode characters to uppercase in C++

本文关键字:转换 字符 unicode c++ 中将      更新时间:2023-10-16

我正在学习c++中的unicode,我很难让它正常工作。我尝试将单个字符视为uint64_t。如果我只需要打印字符,它就可以工作,但问题是我需要将它们转换为大写。我可以将大写字母存储在一个数组中,并简单地使用与存储小写字母相同的索引,但我正在寻找一种更优雅的解决方案。我发现了这个类似的问题,但大多数答案使用宽字符,这不是我可以使用的东西。下面是我的尝试:

#include <iostream>
#include <locale>
#include <string>
#include <cstdint>
#include <algorithm>
// hacky solution to store a multibyte character in a uint64_t
#define E(c) ((((uint64_t) 0 | (uint32_t) c[0]) << 32) | (uint32_t) c[1])
typedef std::string::value_type char_t;
char_t upcase(char_t ch) {
    return std::use_facet<std::ctype<char_t>>(std::locale()).toupper(ch);
}
std::string toupper(const std::string &src) {
    std::string result;
    std::transform(src.begin(), src.end(), std::back_inserter(result), upcase);
    return result;
}
const uint64_t VOWS_EXTRA[]
{
E("å")  , E("ä"), E("ö"), E("ij"), E("ø"), E("æ")
};
int main(void) {
    char name[5];
    std::locale::global(std::locale("sv_SE.UTF8"));
    name[0] = (VOWS_EXTRA[3] >> 32) & ~((uint32_t)0);
    name[1] = VOWS_EXTRA[3] & ~((uint32_t)0);
    name[2] = '';
    std::cout << toupper(name) << std::endl;
}

我希望它打印出字符IJ,但实际上它打印出的字符与开始时相同(ij)。


(EDIT:好的,所以我在这里阅读了更多关于标准c++中unicode支持的信息。似乎我最好的选择是使用ICU或Boost之类的东西。此任务的区域设置。c++基本上将std::string视为二进制数据,因此正确地将unicode字母大写似乎不是一件容易的事情。我认为我使用uint64_t的破解解决方案并不比c++标准库更有用,如果不是更糟的话。如果能提供一个关于如何使用ICU实现上述行为的示例,我将不胜感激。

看一下ICU用户指南。对于简单的(单字符)大小写映射,可以使用u_toupper。对于完整的用例映射,使用u_strToUpper。示例代码:

#include <unicode/uchar.h>
#include <unicode/ustdio.h>
#include <unicode/ustring.h>
int main() {
    UChar32 upper = u_toupper(U'ij');
    u_printf("%lCn", upper);
    UChar src = u'ß';
    UChar dest[3];
    UErrorCode err = U_ZERO_ERROR;
    u_strToUpper(dest, 3, &src, 1, NULL, &err);
    u_printf("%Sn", dest);
    return 0;
}

也如果有人在寻找它,std::towupperstd::towlower似乎工作得很好https://en.cppreference.com/w/cpp/string/wide/towupper