2012-01-12 21 views
2

私は文字の配列にテキストファイルの内容を読み込み、次の簡単なコードを、持っている:はifstreamは、テキストファイルから間違った文字を読み込み

const char* name = "test.txt"; 
std::cout << "Loading file " << name << std::endl; 
std::ifstream file; 
file.open(name); 
file.seekg (0, std::ios::end); 
int length = file.tellg(); 
std::cout << "Size: " << length << " bytes" << std::endl; 
file.seekg (0, std::ios::beg); 
char* buffer = new char[length]; 
file.read(buffer,length); 
file.close(); 
std::cout.write(buffer,length); 

しかし、はifstreamはファイルから文字の間違った番号を読み取っているようだが。各行に1つの追加のchar。私はウェブを検索し、win7のテキストファイルのように、各行の最後に改行(\ n)に加えて改行記号(\ r)が付いているように見えます。しかし、ストリームは何らかの形でこれらの文字を表示しませんが、ファイル内の元の数のシンボルを引き続き使用し、ファイルの末尾からさらにバイトを読み取ります。何とかこの問題を解決することは可能ですか?

役立つ場合:MinGWコンパイラとWindows 7 64ビットを使用します。

+0

多分あなた。代わりに 'readsome'関数を使用して、実際にどれくらい読み込んでいるのか確認できます。 – Nim

答えて

6

あなたはバイナリモードでファイルを開きたいかもしれません:

file.open(name, ios_base::in | ios_base::binary); 

そうでなければ何が起こるかは、標準ライブラリがあなたのために、単一の\nにすべてのWindowsの改行(CR + LF)を変換することです。

これは、ファイルから読み取ることができる文字数がファイルのサイズと同じではないことを意味します。 read()に電話すると、可能な限り多くの文字が読み込まれます。要求された文字数を読み取れない場合は、ストリームのfailbitを設定します。

+0

はい、動作します。ありがとう! –

+0

Windowsの場合。必ずしも他のシステムではありません。 –

+0

あなたは私の一日を保存しました、ありがとうございます。 – withparadox2

0

binaryの読書用ファイル(googleまたはhereを参照)をご覧ください。

0

あなたは非常に間違った(しかし広範な)意見から始まっています。 file.tellg()intを返しません。実装タイプstreamposの 定義済みオブジェクトを返します。クラスタイプでなければならず、 であるか、または整数型に変換できない可能性があります。そして、 が整数型に変換可能である場合(そして、私は実装がわからないが、それは必須ではないにしても、 )、結果の整数が魔法以上のものを表すという保証はないクッキー は、同じ位置に再度熟読することができます。

実際には現代のマシンでは大きな問題ではないでしょう。 UnixとWindowsは、ファイルの先頭からバイト単位でオフセットを返します。 Unixの場合、内部表現の と外部表現のマッピングが1対1であるため、これは正常に動作します。 Windowsの の場合、行末の再マッピングがあります。テキストファイルでは、行 の末尾は0x0D、0x0Aの2バイトシーケンスです。これは、読み取ったときに、 の単一文字'\n'になります。そしてstreampos(整数型に変換されます) は、ファイル内でシークする必要があるバイト単位のオフセットを返します。 は、その位置に到達するために読み取らなければならないcharの数ではありません。 のようなものは、あなたがやっているようですが、これは問題ではありません。割り当てられた バッファは必要以上に大きくなることがありますが、それほど小さくなることはありません

これはメインフレームでは当てはまらないことに注意してください。歴史的には、 で、少なくともメインフレームはブロック指向のファイルを使用し、 streamposの整数値は、ブロック番号の特定のビット数が で、フィールドに分割される可能性があります。 のオフセットブロック。これらがどのように配置されているかに応じて、 のように割り当てられたバッファは簡単に数桁大きくなる可能性があります。または、オフセットが上位ビットに配置されていると小さすぎます。

正確なサイズのバッファを取得する唯一の信頼できる方法は、システムによって異なります。また、Windowsを含む一部のシステムでは、 が存在する可能性があります。

(歴史的に、多くの古いマルチバイト符号化方式は、符号化状態を持っていた 、ためstreamposはクラス型であることが必要である理由は、あなたが が正しくそれに先行 何文字を知らなくても文字をデコードすることができませんでしたのでstreamposです。二つの異なる 情報含む必要:ファイルに追求する位置、および情報について この状態を、私は、しかし、どのような状態に依存するマルチバイト エンコーディングは、今日広く使用さがあるとは思わない)

関連する問題