2013-03-22 44 views
2

我創建了包含字符串表中的RC文件,我想用一些特殊的存儲和檢索UTF-8字符串的文件

字符:öüóúØU Aé。所以我保存了UTF-8編碼的字符串。

但是,當我在我的cpp文件調用,像這樣:

LoadString("hu.dll", 12, nn, MAX_PATH); 

我得到一個奇怪的結果:

Error message with unexpected characters

我該如何解決這個問題?

+0

哦,其他的匈牙利人也是。你好。爲你固定英語(達到一定水平)。 – 2013-03-22 22:42:31

+0

從我記得有關Windows的一點點來看,它本身並不支持UTF8。它可以是一些特定的代碼頁或UTF16。希望這可以幫助。 – syam 2013-03-22 22:44:34

+2

它可能讀取UTF-8就好了。當你嘗試在窗口中顯示它時,問題就來了。 Windows代碼預計它將採用不同的編碼方式。 – 2013-03-22 22:50:45

回答

8

正如其他人在評論中指出的,Windows API不提供對UTF-8編碼文本的直接支持。您無法傳遞函數UTF-8編碼的字符串並獲得您期望的輸出。它會將它們解釋爲本地代碼頁中的字符。要使UTF-8字符串傳遞到Windows API函數(包括MessageBox),需要使用MultiByteToWideChar函數將UTF-8轉換爲UTF-16(Windows調用Unicode或寬字符串) 。爲第一個參數傳遞CP_UTF8標誌是啓用此轉換的魔法。例如:

std::wstring ConvertUTF8ToUTF16String(const char* pszUtf8String) 
{ 
    // Determine the size required for the destination buffer. 
    const int length = MultiByteToWideChar(CP_UTF8, 
              0, // no flags required 
              pszUtf8String, 
              -1, // automatically determine length 
              nullptr, 
              0); 

    // Allocate a buffer of the appropriate length. 
    std::wstring utf16String(length, L'\0'); 

    // Call the function again to do the conversion. 
    if (!MultiByteToWideChar(CP_UTF8, 
          0, 
          pszUtf8String, 
          -1, 
          &utf16String[0], 
          length)) 
    { 
     // Uh-oh! Something went wrong. 
     // Handle the failure condition, perhaps by throwing an exception. 
     // Call the GetLastError() function for additional error information. 
     throw std::runtime_error("The MultiByteToWideChar function failed"); 
    } 

    // Return the converted UTF-16 string. 
    return utf16String;      
} 

然後,一旦你有一個寬字符串,你會顯式調用MessageBox功能,MessageBoxW的寬字符串變量。但是,如果您只需要支持Windows而不是其他任何在任何地方使用UTF-8的平臺,那麼您可能會更容易地使用UTF-16編碼的字符串。這是Windows使用的本機Unicode編碼,您可以將這些類型的字符串直接傳遞給任何Windows API函數。請參閱my answer here以瞭解有關Windows API函數和字符串之間的交互的更多信息。我建議同樣的事情,你像我一樣給其他人:

  • 棒分別wchar_tstd::wstring您的字符和字符串。
  • 始終調用W變體的Windows API函數,包括LoadStringWMessageBoxW
  • 確保UNICODE_UNICODE宏是在包含任何Windows頭文件之前或在項目的構建設置中定義的。