2010-05-17 4 views
9

UTF-8 문자열을 반복하거나 UTF-8 기호의 배열로 분할하는 플랫폼 및 제 3 자 라이브러리에 독립적 인 방법을 검색합니다.C++을 반복하거나 UTF-8 문자열을 기호 배열로 분할 하시겠습니까?

코드 스 니펫을 게시하십시오.

는 해결 : C++ iterate or split UTF-8 string into array of symbols?

+0

C++를 처리하기위한 표준 시설이없는 UTF-8 인코딩 따라서 별도의 라이브러리를 사용하거나 직접 작성하십시오. 자신 만의 글쓰기는 가능하지만 많은 내용이 있습니다. –

+0

네, 그게 제가 질문하는 이유입니다. –

답변

12

작은 플랫폼 독립적 인 UTF8 CPP 라이브러리를 사용하여 해결 :

char* str = (char*)text.c_str(); // utf-8 string 
    char* str_i = str;     // string iterator 
    char* end = str+strlen(str)+1;  // end iterator 

    unsigned char[5] symbol = {0,0,0,0,0}; 

    do 
    { 
     uint32_t code = utf8::next(str_i, end); // get 32 bit code of a utf-8 symbol 
     if (code == 0) 
      continue; 

     utf8::append(code, symbol); // initialize array `symbol` 
    } 
    while (str_i < end); 
1

ICU Library을보십시오.

+0

"제 3 자 라이브러리에 독립적 인 방식" –

+1

+1 ICU는 허용되는 오픈 소스 라이선스에 따라 배포되는 크로스 플랫폼 라이브러리입니다. 운영자가 제 3 자 라이브러리에 대한 의존성을 피하려는 경우 ICU의 소스 코드는 무료로 사용할 수 있지만 1e + 06 줄 이상의 코드가 포함됩니다. –

+1

오픈 소스입니다. 모든 1e + 06 행의 코드가 아닌 iterator 문자열을 사용할 수 있습니다. –

27

정확하게 이해하면 각 UTF-8 문자의 시작을 찾고 싶을 것 같습니다. 그렇다면 해석하는 것이 매우 간단합니다 (해석은 다른 문제입니다). RFC에 의해 잘 정의하지만 참여 얼마나 많은 옥텟의 정의는 다음과 같습니다 예를 들어

Char. number range |  UTF-8 octet sequence 
    (hexadecimal) |    (binary) 
--------------------+--------------------------------------------- 
0000 0000-0000 007F | 0xxxxxxx 
0000 0080-0000 07FF | 110xxxxx 10xxxxxx 
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 

, lb는 UTF-8 문자의 첫 번째 옥텟이있는 경우, 내가 생각하는 옥텟의 수를 결정하는 것이다 다음 뒤얽힌.

unsigned char lb; 

if ((lb & 0x80) == 0)   // lead bit is zero, must be a single ascii 
    printf("1 octet\n"); 
else if ((lb & 0xE0) == 0xC0) // 110x xxxx 
    printf("2 octets\n"); 
else if ((lb & 0xF0) == 0xE0) // 1110 xxxx 
    printf("3 octets\n"); 
else if ((lb & 0xF8) == 0xF0) // 1111 0xxx 
    printf("4 octets\n"); 
else 
    printf("Unrecognized lead byte (%02x)\n", lb); 

궁극적으로 다른 게시물에서 제안 된대로 기존 라이브러리를 사용하는 것이 훨씬 나을 것입니다. 위의 코드는 옥텟에 따라 문자를 분류 할 수 있지만 끝난 후에는 문자로 "수행"하는 데 도움이되지 않습니다. 커프 오프

+0

감사합니다, 유용한 답변, 투표했습니다. –

+0

아름다운 답변! 이것은 내가 찾고 있었던 바로 그 것이다! 감사! –

0

:

// Return length of s converted. On success return should equal s.length(). 
// On error return points to the character where decoding failed. 
// Remember to check the success flag since decoding errors could occur at 
// the end of the string 
int convert(std::vector<int>& u, const std::string& s, bool& success) { 
    success = false; 
    int cp = 0; 
    int runlen = 0; 
    for (std::string::const_iterator it = s.begin(), end = s.end(); it != end; ++it) { 
     int ch = static_cast<unsigned char>(*it); 
     if (runlen > 0) { 
      if ((ch & 0xc0 != 0x80) || cp == 0) return it-s.begin(); 
      cp = (cp << 6) + (ch & 0x3f); 
      if (--runlen == 0) { 
       u.push_back(cp); 
       cp = 0; 
      } 
     } 
     else if (cp == 0) { 
      if (ch < 0x80)  { u.push_back(ch); } 
      else if (ch > 0xf8) return it-s.begin(); 
      else if (ch > 0xf0) { cp = ch & 7; runlen = 3; } 
      else if (ch > 0xe0) { cp = ch & 0xf; runlen = 2; } 
      else if (ch > 0xc0) { cp = ch & 0x1f; runlen = 1; } 
      else return it-s.begin(); // stop on error 
     } 
     else return it-s.begin(); 
    } 
    success = runlen == 0; // verify we are between codepoints 
    return s.length(); 
} 
+0

감사합니다. endianess는이 기능에 중요한가? –

+0

"if (* it <0x80) {u.push_back (* it);} "=> –

+0

'const char * const '에서'char *'로의 변환이 올바르지 않습니다. " –

2

UTF8 CPP 당신이 원하는 것을 정확히

+0

본인이 이미이 라이브러리를 발견했습니다. 나는 코드가 필요했지만 어쨌든 고마워. –

+1

@ 네만 자 대단한 도서관에 감사드립니다! –

관련 문제