2016-12-15 58 views
1

在Windows上使用Visual Studio 2015年比較統一的std :: string與常規 「」 文字或U8 「」 declartion

// Ü 
    // UTF-8 (hex) 0xC3 0x9C 
    // UTF-16 (hex) 0x00DC 
    // UTF-32 (hex) 0x000000DC 

    using namespace std::string_literals; 
    const auto narrow_multibyte_string_s = "\u00dc"s; 
    const auto wide_string_s    = L"\u00dc"s; 
    const auto utf8_encoded_string_s  = u8"\u00dc"s; 
    const auto utf16_encoded_string_s = u"\u00dc"s; 
    const auto utf32_encoded_string_s = U"\u00dc"s; 

    assert(utf8_encoded_string_s  == "\xC3\x9C"); 
    assert(narrow_multibyte_string_s ==  "Ü"); 
    assert(utf8_encoded_string_s  ==  u8"Ü"); 

    // here is the question 
    assert(utf8_encoded_string_s != narrow_multibyte_string_s); 

「\ u00dc」 S是不一樣的U8 「\ u00dc」小號的「u」是不一樣的U8的「u」

顯然用於通常字符串文字默認編碼不是UTF-8(大概UTF-16)和我不能只是比較兩個std :: string而不知道它的編碼前夕他們有相同的語義。

在unicode-C++應用程序開發中執行這種字符串比較的做法是什麼?

例如像這樣的API:

class MyDatabase 
    { 
     bool isAvailable(const std::string& key) 
     { 
     // *compare* key in database 
     if (key == "Ü") 
      return true; 
     else 
      return false; 
     } 
    } 

其他程序可能在UTF-8或默認(?UTF-16)編碼調用isAvailable用的std :: string。我如何保證做適當的比較?

我可以在編譯時檢測到任何編碼不匹配嗎?

注:我更喜歡C++ 11/14的東西。 不想的std :: string比的std :: wstring的

+0

UTF-16只與'wstring'一起使用,在你的問題中每提及一次肯定是錯誤的猜測。默認編碼可能是編譯時的當前ANSI代碼頁。或者更確切地說,默認值是不重新編碼,源文件的編碼被保留,並且語法處理的目的是,編譯器假定爲ANSI。 –

回答

2

"\u00dc"是什麼編譯器/操作系統默認的8位編碼恰好是編碼的char[],因此它可以在不同的機器不同。在Windows上,這往往是操作系統的默認Ansi編碼,或者它可能是源文件保存爲的編碼。

L"\u00dc"是與任一UTF-16或UTF-32編碼的wchar_t[],取決於wchar_t編譯器的定義(這是在Windows 16位,所以UTF-16)。編碼爲UTF-8的char[]

u"\u00dc"是以UTF-16編碼的char16_t[]

U"\u00dc"是以UTF-32編碼的char32_t[]

""s後綴簡單地返回一個std::stringstd::wstringstd::u16string,或std::u32string,取決於是否一char[]wchar_t[]char16_t[],或char32_t[]傳遞給它。

比較兩個字符串時,請確保它們首先處於相同的編碼。這對於您的char[]/std::string數據尤爲重要,因爲它可以是任意數量的8位編碼,具體取決於涉及的系統。如果應用程序本身生成字符串,這並不是什麼問題,但是如果一個或多個字符串來自外部來源(文件,用戶輸入,網絡協議等),這很重要。

在您的示例中,"\u00dc""Ü"不一定能保證產生相同的char[]序列,這取決於編譯器如何解釋這些不同的文字。但即使他們這樣做(在你的例子中似乎是這種情況),他們都不會生成UTF-8(你必須採取額外的措施來強制這樣做),這就是爲什麼你與utf8_encoded_string_s的比較失敗的原因。

因此,如果您希望字符串文字爲UTF-8,請使用u8""來確保。如果您從外部源獲取字符串數據並需要使用UTF-8,請儘快將其轉換爲UTF-8編碼(如果尚未編碼)(這意味着您必須知道編碼器使用的編碼外部源)。

+1

'L「\ u00dc」'編碼在「支持的語言環境中指定的最大擴展字符集」[basic.fundamental]中,不保證是UTF-16/32(例如,它可能因「LC_CTYPE」而異) 。 –

相關問題