我正在学习有关unicode的C++,我很难让它正常工作。我尝试将单个字符视为uint64_t。如果我所需要的只是打印出字符,它的工作原理是,但问题是我需要将它们转换为大写字母。我可以将大写字母存储在数组中,只需使用与小写字母相同的索引,但我正在寻找更优雅的解决方案。我发现这个类似的question,但大多数答案使用宽字符,这是我不能使用的。以下是我已经尝试:如何将Unicode字符转换为大写的C++
#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
)。
(编辑:OK,让我了解更多有关标准C++ here的Unicode支持这似乎是我最好的选择是使用像ICU或Boost.locale此任务的C++基本治疗。 std :: string作为一个二进制数据blob,所以似乎不是一个简单的任务大写unicode字母正确。我认为我的hacky解决方案使用uint64_t没有任何方式比C++标准库更有用,如果不是甚至更糟糕的是,我很感激如何使用ICU实现上述行为。)
请不要试图假装Unicode是固定宽度编码。 –
@NicolBolas抱歉,我对unicode非常不熟悉,我尝试使用常规字符串,但无法使用单字符工作。 – Linus
除非使用非常特殊的编译器,否则'std :: locale :: global(std :: locale(“sv_SE.UTF8”))'与Windows不兼容。微软的运行时不支持UTF-8语言环境。参见'setlocale'的文档。 –