2012-12-11 32 views
2


我的程序從文件中讀取文本並將其置於組合框中。
當文件包含英文字符的文本時,一切正常。
當它包含一些波蘭語字母時,它們將被替換爲奇怪的字符。
文件編碼是UTF-8(不含BOM)。在WinAPI中使用Unicode的奇怪字符改爲國家字母

myCombo = CreateWindowExW(WS_EX_CLIENTEDGE, (LPCWSTR)L"COMBOBOX", NULL, 
          WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, 
          a, b, c, d, 
          hwnd, (HMENU)ID_COMBO, hThisInstance, NULL); 

wstring foo; 
wifstream bar("theTextFile.txt"); 
getline(bar, foo); 
SendMessageW(myCombo, CB_ADDSTRING, (WPARAM)0, (LPARAM)(foo.c_str())); 

如何才能讓我的程序顯示正確的國家字母?

PS。對不起,我的英文不好:)

+0

wifstream是maddingly傻類,這是寬約它的唯一的事情就是你傳遞文件的名稱。你在你的代碼片段中摸索到了哪些內容。該文件的實際內容不被認爲是寬的,也不是utf-8。不是沒有使用正確的codecvt <>來填充它。檢查您的CRT的樣板實現,通常類似於「codecvt_utf8」。 –

+0

@HansPassant'std :: wifstream'不接受寬字符串作爲文件名。微軟的實施可以作爲擴展,但這與廣泛的流無關;即使他們狹窄的fstream類也接受寬字符串文件名。他們這樣做只是因爲他們的文件API被打破了狹窄的字符串。 – bames53

+0

寬流的目的不是對存儲爲寬字符的數據進行操作,而是爲了讓程序員看不到內部和外部表示之間的轉換。唯一的問題是,固定寬度的代碼點表示法對於其預期目的是毫無價值的(即保持國際文本處理像處理英文文本一樣簡單),所以沒有人使用它們打算使用的寬字符。 – bames53

回答

3

wifstream默認情況下不會在Windows上讀取UTF-8文本。流的語言環境中的codecvt方面是將文件中的字節轉換爲wchar_t,因此您需要設置它以便它將轉換爲您想要的wchar_t

事情是這樣的:

#include <fstream> 
#include <string> 

#include <locale> // std::locale 
#include <codecvt> // std::codecvt_utf8_utf16 
#include <memory> // std::unique_ptr 

#include <Windows.h> // WriteConsoleW 

int main(int argc, const char * argv[]) 
{ 
    std::wstring foo; 
    std::wifstream bar("theTextFile.txt"); 

    typedef std::codecvt_utf8_utf16<wchar_t, 0x10FFFF, std::consume_header> codecvt; 
    std::unique_ptr<codecvt> ptr(new codecvt); 
    std::locale utf8_locale((std::locale()), ptr.get()); 
    ptr.release(); 
    bar.imbue(utf8_locale); 

    std::getline(bar, foo); 

    DWORD n; 
    WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), foo.c_str(), foo.size(), &n, NULL); 
} 
+0

對。默認轉換來自您的系統代碼頁。爲什麼Windows不會進入21世紀,並且讓您使用UTF-8編碼頁面已經超出了我的想象。 –

+0

UTF-8是一個代碼頁(65001)。 [但它不能是ANSI代碼頁](http://blogs.msdn.com/b/michkap/archive/2007/01/03/1392379.aspx)。 –