2014-02-11 66 views
0

使用C++ 11,我怎樣才能從UTF-8編碼std::string中獲取文本中每個字符的Unicode值爲uint32_t如何從UTF-8字符串的每個字符獲取UNICODE代碼?

喜歡的東西:

void f(const std::string &utf8_str) 
{ 
    for(???) { 
     uint32_t code = ???; 

     /* Do my stuff with the code... */ 
    } 
} 

是否假定主機系統區域設置爲UTF-8可以幫助? C++ 11提供哪些標準庫工具來完成這項任務?

回答

4

您可以將字符串簡單地轉換爲UTF-32編碼的一個,使用所提供的轉換面和std::wstring_convert<locale>

#include <codecvt> 
#include <locale> 
#include <string> 

void foo(std::string const & utf8str) 
{ 
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv; 
    std::u32string utf32str = conv.from_bytes(utf8str); 

    for (char32_t u : utf32str) { /* ... */ } 
} 
+0

你知道怎麼去,而不是UTF-8,的codecvt爲系統本地編碼? – lvella

+0

@lvella:您可以使用['mbrtoc32'](http://en.cppreference.com/w/cpp/string/multibyte/mbrtoc32)將系統的窄編碼轉換爲UTF32。鏈接頁面底部的表格顯示了所有可用的組合。 ([我不確定](http://stackoverflow.com/questions/7562609/what-does-cuchar-provide-and-where-is-it-documented)如果''被廣泛實施,但。 ) –

+1

@lvella系統的本地編碼而不是UTF-8?如果您的意思是像GB18030(另一種8位Unicode格式),那麼您可以使用codecvt_byname或使用use_facet將其從語言環境中提取出來。 [這個例子](http://en.cppreference.com/w/cpp/locale/wstring_convert/wstring_convert)展示瞭如何使用它構建一個wstring_convert。 – Cubbi

1

使用<utf8.h>http://utfcpp.sourceforge.net/你可以編寫:

static inline void fix_utf8_string(std::string& str) 
{ 
    std::string temp; 
    utf8::replace_invalid(str.begin(), str.end(), back_inserter(temp)); 
    str = temp; 
} 

static inline bool valid_utf8_cstr(const char*s) 
{ 
    if (!s) return false; 
    const char* e = s+strlen(s); 
    return utf8::is_valid(s,e); 
} 

static inline size_t 
utf8_length(const char*s) 
{ 
    if (!s) return 0; 
    const char* e = s+strlen(s); 
    return utf8::distance(s,e); 
} 


// apply a function to every code point, exiting if that function 
// gives true and return the number of visited code points 
static inline size_t 
utf8_foreach_if(const char*s, 
       std::function<bool(uint32_t,size_t)>f) 
{ 
    if (!s) return 0; 
    size_t ix=0; 
    const char*pc = s; 
    while(*pc) 
    { 
     const char*epc 
     = (pc[1]==0)?(pc+1):(pc[2]==0) 
       ?(pc+2):(pc[3]==0)?(pc+3):(pc+4); 
     uint32_t c = utf8::next(pc,epc); 
     if (f(c,ix)) break; 
     ix++; 
    }; 
    return ix; 
} 

static inline size_t 
utf8_foreach_if(const std::string& s, 
       std::function<bool(uint32_t,size_t)>f) 
{ 
    if (s.empty()) return 0; 
    size_t ix=0; 
    const char*pc = s.c_str(); 
    const char*epc = pc + s.size(); 
    while(*pc) 
    { 
     uint32_t c = utf8::next(pc,epc); 
     if (f(c,ix)) break; 
     ix++; 
    }; 
    return ix; 
} 

這是從一些代碼以GPLv3許可,我會在幾周或幾個月內釋放提取。

相關問題