2011-08-12 16 views
4

私は奇妙な問題を抱えている、 私はgetlineの通報及び「奇妙な文字」

wifstream a("a.txt"); 
wstring line; 
while (a.good()) //!a.eof() not helping 
{ 
    getline (a,line); 
     //... 
    wcout<<line<<endl; 

} 

を使用して、それがこの http://www.speedyshare.com/files/29833132/a.txt リンクについて(申し訳ありませんようにtxtファイルのためにうまく動作しますが、それだけで80ありますそれでは、改行のic/pが失われてしまったら のようになりますが、ロードを停止している行には例えば水(http://en.wikipedia.org/wiki/UTF-16/UCS-2#Examplesから)を追加します。私は間違った印象を受けていましたが、wstringを1つの入力として受け取り、他の人がtxtの入力を噛むことができるようなgetlineがありました... ファンキーな文字が含まれていてもファイルのすべての行を読み取る方法はありますか?

+1

「getline 」を試してください。 –

+1

あなたのユーザ名としか一致しない何らかの理由で、wifstreamのデフォルトは8ビット文字になります。他のエンコーディングを認識するようにstd :: codecvtを使用する必要があります。 –

+2

@ kerrek \t getline (a、line); は同じ(g ++ 4.6、linux)に失敗します。それは引数からテンプレートのパラメータを取得する必要がありますか? – NoSenseEtAl

答えて

6

非常に満足のいく答えは、問題の特定の文字エンコーディングを理解するロケールで入力ストリームにインプレッションする必要があるということです。選択するロケールがわからない場合は、空のロケールを使用できます。 (未テスト)例えば

std::wifstream a("a.txt"); 
std::locale loc(""); 
a.imbue(loc); 

は残念ながら、ロケールは、特定のプラットフォームのために利用可能であるかを決定し、ましてや文字エンコーディングに基づいていずれかを選択する標準的な方法はありません。

上記のコードは、ロケールの選択をユーザーの手元に置いており、可能性のあるもの(たとえばen_AU.UTF-8)に設定した場合、すべてが正式に機能する可能性があります。

この場合、おそらくiconvまたはICUなどのサードパーティのライブラリを使用する必要があります。

この回答は参考になりましたblog entry(自己宣伝のお詫び)

+0

こんにちは、あなたのソリューションは "働いた"。それは読書をクラッシュしませんが、私はまだ得る?私はそれをwcoutしようとすると、実際の文字のinstad ...(私はちょうどだった: "それを試してみてください..."))何か意味がある場合でも私は知らないwcoutは助けwcout。今、私はなぜutf 16とiostreamsのすべての憎悪を参照してください... :)まだ素敵な応答のためのtnx。 – NoSenseEtAl

3

問題はグローバル関数getline (a,line)への呼び出しにあります。これにはstd::stringが必要です。 getline関数の代わりにstd::wistream::getlineメソッドを使用します。

+0

たぶん彼はwstringでそれを望んでいるので、getline関数を使用していますか? wistreamのgetlineメソッドはwstringに出力されません。 – Alastair

3

C++ fstreamsは、filebufsへのI/Oを削除します。 filebufsは常に "raw bytes"をディスクから読み込み、ストリームロケールのcodecvtファセットを使ってこれらの生のバイト間を "内部エンコーディング"に変換します。

wfstreambasic_fstream<wchar_t>であり、したがって、ロケールのcodecvt<wchar_t, char>wchar_t Sにディスクから読み取られたバイトを変換するために使用basic_filebuf<wchar_t>を有しています。 UCS-2でエンコードされたファイルを読み取る場合、その変換は外部エンコードがUCS-2であることを「知っている」コーデックで実行する必要があります。したがって、そのようなコーデックを持つロケールが必要です(たとえば、this SO questionを参照)。

デフォルトでは、ストリームのロケールはストリーム構築時のグローバルロケールです。特定のロケールを使用するには、ストリーム上でimbue() -dにする必要があります。