2017-07-26 111 views
0

隨着code bellow我可以採取代碼字符的wstring。 如果codepoint> 65535錯誤的wstring。如何做到這一點?from ascii codepoint of character to wstring

wstring giveWStringFromASCII(size_t i) 
{ 
    wchar_t character[]= {i,0}; 
    return wstring(character); 
} 
+0

['std :: u32string'](http://en.cppreference.com/w/cpp/string/basic_string)是否適合您? –

+0

不,必須從碼點> 65535,0xffff –

+0

ASCII和> 65535?不可能!你在談論Unicode嗎? – 2017-07-26 22:20:19

回答

1

std::wstring使用wchar_t元件。 wchar_t不可移植,因爲它在Windows上使用2個字節(UTF-16編碼),但在其他平臺上使用4個字節(UTF-32編碼)。

存儲在size_t中的Unicode代碼點只能在非Windows平臺上按原樣分配給wchar_t。在Windows上,一個wchar_t只能處理BMP(UCS-2)範圍(U + 0000 - U + FFFF)中的Unicode字符。更高的代碼點必須編碼爲2 wchar_t元素,在UTF-16中稱爲「代理對」。

你所顯示的內容只能在非Windows平臺上運行。如果你需要支持多個平臺,你將不得不相應#ifdef的代碼,例如:

std::wstring giveWStringFromCodepoint(size_t cp) 
{ 
    #ifdef _WIN32 

    wchar_t ch[2]; 
    if (cp < 0x10000) 
    { 
     ch[0] = (wchar_t) cp; 
     return std::wstring(ch, 1); 
    } 
    else 
    { 
     cp -= 0x10000; 
     ch[0] = (wchar_t) ((cp >> 10) + 0xD800); 
     ch[1] = (wchar_t) ((cp & 0x3FF) + 0xDC00); 
     return std::wstring(ch, 2); 
    } 

    #else 

    wchar_t ch = (wchar_t) i; 
    return std::wstring(&ch, 1); 

    #endif 
} 

或者:

std::wstring giveWStringFromCodepoint(size_t cp) 
{ 
    #if (WCHAR_MAX > 0xFFFF) 

    wchar_t ch = (wchar_t) i; 
    return std::wstring(&ch, 1); 

    #else 

    wchar_t ch[2]; 
    if (cp < 0x10000) 
    { 
     ch[0] = (wchar_t) cp; 
     return std::wstring(ch, 1); 
    } 
    else 
    { 
     cp -= 0x10000; 
     ch[0] = (wchar_t) ((cp >> 10) + 0xD800); 
     ch[1] = (wchar_t) ((cp & 0x3FF) + 0xDC00); 
     return std::wstring(ch, 2); 
    } 

    #endif 
} 

或者:

std::wstring giveWStringFromCodepoint(size_t cp) 
{ 
    if (sizeof(wchar_t) > 2) 
    { 
     wchar_t ch = (wchar_t) i; 
     return std::wstring(&ch, 1); 
    } 
    else 
    { 
     wchar_t ch[2]; 
     if (cp < 0x10000) 
     { 
      ch[0] = (wchar_t) cp; 
      return std::wstring(ch, 1); 
     } 
     else 
     { 
      cp -= 0x10000; 
      ch[0] = (wchar_t) ((cp >> 10) + 0xD800); 
      ch[1] = (wchar_t) ((cp & 0x3FF) + 0xDC00); 
      return std::wstring(ch, 2); 
     } 
    } 
} 

話雖這麼說,你是最好使用第三方Unicode庫(如ICONV或ICU)來處理這種類型的轉換。

如果您使用C++ 11或更高版本,它有std::u16stringstd::u32string可用於避免std::wstring的可移植性問題。考慮儘可能使用它們。或者,至少在處理UTF轉換時,如果不使用第三方庫,請考慮使用std::wstring_convert

+1

而不是檢查Windows(實際上是'#ifdef _WIN32'),我會檢查'wchar_t'的大小 - 它更容易,更清晰和更正確。 –

+0

您可以檢查'WCHAR_MAX'的值。 '#if WCHAR_MAX == 65535' ...'#elif WCHAR_MAX == 4294967295' ...'#else'' #error unsupported wchar_t size'' #endif'。 –

+0

感謝所有。所以依靠OS。 –