2016-09-18 24 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

相关问题