2016-09-18 1 views
2

저는 C++의 유니 코드에 대해 배우고 있으며 제대로 작동하려면 어려움을 겪고 있습니다. 개별 문자를 uint64_t로 처리하려고합니다. 그것은 내가 필요한 모든 문자를 인쇄하는 것입니다 작동하지만 문제는 내가 그들을 대문자로 변환해야합니다. 대문자를 배열에 저장하고 소문자로 사용하는 것과 동일한 색인을 사용할 수 있지만 좀 더 우아한 해결책을 찾고 있습니다. 이 비슷한 question을 찾았지만 대부분의 답변에서 와이드 문자가 사용되었습니다. 사용할 수없는 문자입니다. 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에서 유니 코드 지원에 대한 자세한 내용을 내 가장 좋은 방법이 작업을 위해 ICU 또는 Boost.locale 같은 것을 사용하는 것 같다 C++ 본질적으로 취급합니다.. std :: string을 바이너리 데이터의 BLOB로 사용하면 유니 코드 문자를 올바르게 대문자로 변환하는 것이 쉽지 않은 것 같습니다. uint64_t를 사용하는 내 해킹 솔루션은 C++ 표준 라이브러리보다 더 유용하지 않습니다. ICU를 사용하여 위에서 언급 한 동작을 달성하는 방법에 대한 예를 들어 주셔서 감사드립니다.

+0

유니 코드가 고정 폭 인코딩 인 것처럼 가장하지 마십시오. –

+0

@NicolBolas 유감스럽게 생각합니다. 유니 코드를 사용하는 데 익숙하지 않습니다. 정규 문자열을 사용해 보았지만 하나의 문자로 작동하지 못했습니다. – Linus

+0

매우 특별한 컴파일러를 사용하지 않는 한'std :: locale :: global (std :: locale ("sv_SE.UTF8"))'은 Windows와 호환되지 않습니다. Microsoft의 런타임은 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

관련 문제