2012-07-25 45 views
4

我正在編寫一個程序來獲取UCS-2 Little Endian中* .rc文件編碼的信息。如何讀取UCS-2文件?

int _tmain(int argc, _TCHAR* argv[]) { 
    wstring csvLine(wstring sLine); 
    wifstream fin("en.rc"); 
    wofstream fout("table.csv"); 
    wofstream fout_rm("temp.txt"); 
    wstring sLine; 
    fout << "en\n"; 
    while(getline(fin,sLine)) { 
    if (sLine.find(L"IDS") == -1) 
     fout_rm << sLine << endl; 
    else 
     fout << csvLine(sLine); 
    } 
    fout << flush; 
    system("pause"); 
    return 0; 
} 

在 「en.rc」 的第一行是#include <windows.h>sLine如下所示:

[0]  255 L'ÿ' 
[1]  254 L'þ' 
[2]  35 L'#' 
[3]  0 
[4]  105 L'i' 
[5]  0 
[6]  110 L'n' 
[7]  0 
[8]  99 L'c' 
.  . 
.  . 
.  . 

這個程序可以正確地計算出對於UTF-8。我怎樣才能做到UCS-2?

+0

你的示例代碼甚至不會編譯。 – 2012-07-25 06:39:19

+0

當我粘貼它時,我錯過了宣言行。代碼已更新 – 2012-07-25 06:48:19

+0

請訪問:http://www.codeproject.com/Articles/38242/Reading-UTF-8-with-C-streams – 2012-07-25 06:58:33

回答

6

寬流使用寬流緩衝區來訪問文件。寬流緩衝區從文件讀取字節並使用其codecvt facet將這些字節轉換爲寬字符。缺省編碼方面是std::codecvt<wchar_t, char ,std::mbstate_t>,其在wchar_tchar(即,像mbstowcs()那樣的本地字符集之間進行轉換。

你沒有使用原始字符集,所以你想要的是一個codecvt方面,將UCS-2作爲多字節序列讀取並將其轉換爲寬字符。

#include <fstream> 
#include <string> 
#include <codecvt> 
#include <iostream> 

int main(int argc, char *argv[]) 
{ 
    wifstream fin("en.rc", std::ios::binary); // You need to open the file in binary mode 

    // Imbue the file stream with a codecvt facet that uses UTF-16 as the external multibyte encoding 
    fin.imbue(std::locale(fin.getloc(), 
       new std::codecvt_utf16<wchar_t, 0xffff, consume_header>)); 

    //^We set 0xFFFF as the maxcode because that's the largest that will fit in a single wchar_t 
    // We use consume_header to detect and use the UTF-16 'BOM' 

    // The following is not really the correct way to write Unicode output, but it's easy 
    std::wstring sLine; 
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> convert; 
    while (getline(fin, sLine)) 
    { 
     std::cout << convert.to_bytes(sLine) << '\n'; 
    } 
} 

請注意,這裏有一個問題UTF-16wchar_t的用途是一個wchar_t代表一個碼點。然而,Windows使用UTF-16,其代表一些代碼點作爲兩個wchar_t s。這意味着標準API在Windows中不能很好地工作。

在這裏的後果是,當文件包含代理對,codecvt_utf16將讀取對,將其轉換爲一個單一的代碼點值大於16位,必須將值截斷爲16位以堅持在wchar_t。這意味着這個代碼真的只限於UCS-2。我已將maxcode模板參數設置爲0xFFFF以反映此情況。

有一些其他的問題wchar_t,你可能只想避免它完全:因爲它使用未聲明的變量`fout_rm` What's 「wrong」 with C++ wchar_t?