我正在学习C ++中的unicode,但我很难让它正常工作。我尝试将单个字符视为uint64_t。它的工作原理如果我需要它是打印字符,但问题是我需要将它们转换为大写。我可以将大写字母存储在数组中,只需使用与小写字母相同的索引,但我正在寻找更优雅的解决方案。我发现这个类似question,但大多数答案都使用宽字符,这不是我可以使用的。以下是我的尝试:
#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] = '\0';
std::cout << toupper(name) << std::endl;
}
我希望这会打印出字符IJ
,但实际上它会打印出与开头相同的字符(ij
)。
(编辑:好的,所以我在标准C ++ here中阅读了更多关于unicode支持的内容。我最好的选择是使用类似ICU或Boost.locale的内容C ++本质上将std :: string视为二进制数据的blob,所以使用uint64_t的hacky解决方案似乎并不比C ++更有用。标准库,如果不是更糟。我会很感激如何使用ICU实现上述行为。)
答案 0 :(得分:2)
查看ICU User Guide。对于简单(单字符)大小写映射,您可以使用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("%lC\n", upper);
UChar src = u'ß';
UChar dest[3];
UErrorCode err = U_ZERO_ERROR;
u_strToUpper(dest, 3, &src, 1, NULL, &err);
u_printf("%S\n", dest);
return 0;
}
答案 1 :(得分:0)
如果还有其他人正在寻找它,std::towupper
和std::towlower
似乎也可以正常工作
https://en.cppreference.com/w/cpp/string/wide/towupper