8

私は奇妙な問題を抱えています、私は使用します

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バイトなので取得するのに問題はありません。 SO改行のic/pが失われる場合)しかし、たとえば水( http://en.wikipedia.org/wiki/UTF-16/UCS-2#Examplesから)をロードする行である任意の行に追加すると停止します。wstring を 1 つの入力として受け取り、wifstream を他の入力として取る getline は、任意の txt 入力を噛むことができるという間違った印象を受けました...ファンキーな文字が含まれていても、ファイル内のすべての行を読み取る方法はありますか?

4

3 に答える 3

8

あまり満足できない答えは、問題の特定の文字エンコーディングを理解するロケールを入力ストリームに吹き込む必要があるということです。選択するロケールがわからない場合は、空のロケールを使用できます。

例(未テスト):

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

残念ながら、特定のプラットフォームで使用できるロケールを判断する標準的な方法はなく、文字エンコーディングに基づいて選択する方法はありません。

上記のコードは、ロケールの選択をユーザーの手に委ねます。ユーザーがそれをもっともらしいもの (例: en_AU.UTF-8) に設定すると、すべてうまくいく可能性があります。

これに失敗した場合は、おそらくiconvICUなどのサードパーティ ライブラリに頼る必要があります。

このブログエントリも関連しています(自己宣伝のための謝罪)。

于 2011-08-12T13:12:55.543 に答える
4

C++ fstream は、I/O を filebuf に委譲します。filebufs は常にディスクから「生のバイト」を読み取り、ストリーム ロケールの codecvt ファセットを使用して、これらの生のバイトを「内部エンコーディング」に変換します。

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

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

于 2011-08-12T13:12:00.563 に答える
4

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

于 2011-08-12T13:09:18.050 に答える