2013-11-25 16 views
5

私はいくつかの中国のWebファイルを取得するためにWebクローラを書いています。取得したファイルはutf-8でエンコードされています。 URLや漢字を抽出するなどの解析を行うには、これらのファイルを読む必要があります。しかし、ファイルをstd :: string変数に読み込んでコンソールに出力すると、漢字がガベージ文字になることがわかりました。 boost :: regexをstd :: string変数に適用し、漢字以外のすべてのURLを抽出できます。漢字を含むUTF-8でエンコードされたファイルを読み込み、コンソールで正しく出力するにはどうすればよいですか?

どうすれば問題を解決できますか?

P.S.私のCPPファイルはデフォルトでANSIとしてエンコードされ、オペレーティングシステムは中国語のWin8です。一般的に

+0

「コードページ」をUTF-8からコンソールが漢字に使用するコードページに変更する必要があるように聞こえます。 MultiByteToWideCharを呼び出してUTF-8からUnicodeに変更し、続いてWideCharToMultiByteを使用してUnicodeからローカルコードページに変更します。 – john

+0

おそらくコンソールの故障です。 '>' 'ファイルを試してみてください。有効なUTF-8が中国語の文字であると判明した場合、プログラムはうまくいきます。これはWindowsの質問です。 (もちろん、Windowsを回避するためにあなたのプログラムを変更する必要があるかもしれませんが、誰が間違っているのか分かります) – aib

+0

@aibはい、std :: string変数を別のファイルにリダイレクトすると、 Chiese文字を含むUTF-8。私のコンソールのコードページは '' 936(ANSI/OEM - 简体中文GBK) ''です。 –

答えて

7

このコードは役立つかもしれません(VC++ 2010でコンパイルされました)。私は非ラテン文字を含むUTF-8ファイルでテストしましたが、うまくいくように見えますが、中国語の文字でうまく動作するかどうかはわかりません。詳細については、_setmodeおよびcodecvt_utf8の次のリンクを確認してください。

#include <iostream> 
#include <fstream> 
#include <string> 
#include <locale> 
#include <codecvt> 
#include <fcntl.h> 
#include <io.h> 

using namespace std; // Sorry for this! 

void read_all_lines(const wchar_t *filename) 
{ 
    wifstream wifs; 
    wstring txtline; 
    int c = 0; 

    wifs.open(filename); 
    if(!wifs.is_open()) 
    { 
     wcerr << L"Unable to open file" << endl; 
     return; 
    } 
    // We are going to read an UTF-8 file 
    wifs.imbue(locale(wifs.getloc(), new codecvt_utf8<wchar_t, 0x10ffff, consume_header>())); 
    while(getline(wifs, txtline)) 
     wcout << ++c << L'\t' << txtline << L'\n'; 
    wcout << endl; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    // Console output will be UTF-16 characters 
    _setmode(_fileno(stdout), _O_U16TEXT); 
    if(argc < 2) 
    { 
     wcerr << L"Filename expected!" << endl; 
     return 1; 
    } 
    read_all_lines(argv[1]); 
    return 0; 
} 

期待通りに中国語の文字が見えない場合は、必ずコンソールがサポートするフォントを使用されていることを確認UTF-16(すなわち、ビットマップフォントを使用しないでください)。

+1

あなたのソリューションは他のプラットフォームで動作しましたか、WindowsではVCのみでしたか? –

1

w変異体、(wstringwfstreamwcout)を使用し、文字列リテラルの前にLをハングアップ、要件に合わせてロケールを設定します。 locale::global(locale(""))は環境のデフォルトと一致するように設定され、次にそのデフォルトに従って実行されていない各ストリームで設定されます。端末のロケール設定はwcout.imbue(locale("Chinese_China.936"))might be Microsoft's nameです。これは常に私が望むことをするのに十分であり、それがあなたのためにもうまくいくことを願っています。

#include <iostream> 
#include <locale> 
using namespace std; 
int main() { 
    locale::global(locale("")); 
    wstring word; 
    while (wcin >>word) 
    wcout<<word<<'\n'; 
    wcout<<L"好運n"; 
} 
0

文字を正しく表示する必要がある場合は、GNUのlibiconvを使用できます。 URLだけを処理する必要がある場合は、std :: stringが正常に動作します。 問題はWindowsコンソールのコードページであり、文字列自体ではありません。 ロケールの使用はosとstdC++のlibの実装に依存しているので、私は使用をお勧めしません。

ウィンドウのMultiByteToWideCharが役立つかもしれませんが、関数が文字列の変換をどのように実行するかについてMSの仕様を確認する必要があります。