2

テキスト ファイルのサイズを示すコード スニペットを見つけました。

ifstream file("xmlfile.xml",ios::in);
//get size
file.seekg (0, ios::end);
int length = file.tellg();
file.seekg (0, ios::beg);

// allocate memory:
char* buffer = new char [length];

// read data as a block:
file.read (buffer,length);
file.close();
buffer[length-1] = '\0';
printf("%s",buffer);

問題は、私が読みたい小さなxmlファイルで、それを完全に読み取りますが、ファイル内のCRの数に等しいことがわかったので、最後に多くの「=」記号を残すことです。EOL を Unix に切り替えることで問題は解決しましたが、Windows EOL での印刷に問題があるのはなぜですか?

サンプル XML:

<?xml version="1.0"?>
<catalog>




(EOL)

そして、printf が出力するもの:

<?xml version="1.0"?>
<catalog>





══════
4

3 に答える 3

3

2 つの問題があります。

seekとを使用しtellてファイル サイズを取得すると、ファイル内のバイト数がわかります。ディスク上の Windows EOL は 2 バイトです。ただしread、テキスト モードで開かれたファイルで読み取ると、EOL はメモリ内で 1 バイトになります。次のようにファイルをバイナリモードで開くことで、これを修正できます。

ifstream file("xmlfile.xml",ios::in | ios::binary);

もう 1 つの問題は、ファイルの内容を null で終了する文字列として扱いたい場合、NULL ターミネータに余分なスペースを割り当てる必要があることです。現状では、ファイルの最後のバイトを NULL で上書きしています。これを行う必要があります:

char* buffer = new char [length+1];

buffer[length] = '\0';
于 2012-06-11T17:17:16.663 に答える
3

この問題が発生するのは、Windows では各行の末尾にキャリッジ リターン + ライン フィード文字が使用されているのに対し、Linux ではそのうちの 1 つしか使用されていないためです。

ifstream がテキスト モードで開きます。テキスト ファイルの絶対サイズを返しますが、その数のテキスト文字を読み取るように指示します。Windows が自動的に使用しない余分な文字を破棄しているようで、ファイルの末尾を超えて読み取ってしまいます。

これを修正するには、.gcount() を使用して読み取った文字数を取得できます。

于 2012-06-11T17:11:07.697 に答える
2

何が起こっているのかを正しく理解していれば、バイト単位tellgで位置を伝えますが、読み取り中にWindowsの行末はプレーンな';に変換されます。このため、 によって参照される位置は、「欠落している」CR の数の「実際の」末尾の後にあります。'\nbuffer[length]

この問題を回避するには、ファイル呼び出しを読み取った後file.gcount()、最後の読み取り中に読み取られた文字数を取得し、それをバッファーを終了する位置として使用します。

于 2012-06-11T17:10:59.113 に答える