我正在學習有關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'的文檔。 –