2016-09-18 64 views
2

我正在學習有關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實現上述行爲。)

+0

請不要試圖假裝Unicode是固定寬度編碼。 –

+0

@NicolBolas抱歉,我對unicode非常不熟悉,我嘗試使用常規字符串,但無法使用單字符工作。 – Linus

+0

除非使用非常特殊的編譯器,否則'std :: locale :: global(std :: locale(「sv_SE.UTF8」))'與Windows不兼容。微軟的運行時不支持UTF-8語言環境。參見'setlocale'的文檔。 –

回答

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; 
} 
+0

謝謝,對於已接受的答案已晚。我花了幾個小時才讓ICU工作。我對「未定義的函數參考」錯誤有很多問題。 – Linus

相關問題