2012-04-20 10 views
3

私はいくつかの内部ファイルを追加することができます。追加するファイルは、ファイルに追加するたびに\nという文字が追加された後です。しかし理論的には、ファイルへの追加が失敗し、ファイルが破損する可能性があります。そのため、ファイルを開くたびに、最後の有効な、最後のEOLの後の位置に移動します。このコードは、それを行うだろう:最後のEOL後にファイルの内容を削除するにはどうすればよいですか?

// Not using ios::app instead of ios::ate | ios::out because it will 
// put print pointer to the EOF every time before writing. 
fstream file(name.c_str(), ios::binary | ios::ate | ios::out | ios::in); 
if(!file.is_open()) { 
    cerr << "Error in oppening file " << name << endl; 
    exit(EXIT_FAILURE); 
} else { 
    while(0 != file.tellp()) //if file is not empty 
    { 
     file.seekg(-1, ios_base::cur); 
     if(0 == file.tellg() || file.get() == '\n') { 
      break; 
     } 
     file.seekg(-1, ios_base::cur); 
    } 
    file.seekp(of.tellg()); 
} 
//{1} 
//Use file for appending to... 

をしかし、ファイルに付加されなければならない部分の長さは、ファイル内の最後のEOL文字から始まる部分の長さよりも低い場合には、正常に動作しません。だからこそ{1}ポジション私はfile.tellp()から始まるファイル内容を最後まで削除したい。

どうすればいいですか?

答えて

1

これを実行するための移植可能な方法はありません(完全な説明については、James Kanzeの回答をご覧ください)。

POSIXシステムを使用している場合は、ftruncatehereを参照)を使用して、ファイルの長さを一定の長さに設定できます。私はC++の同等物を知らない(詳細についてはthis questionを参照してください)

+0

'ftruncate'はUnixのみです。また、引数としてストリームまたは 'FILE * 'を取りません。 –

+0

これは理想的ではありません(私が言ったように、私はC++のことを知らない)。私はそれがPOSIXのコマンドであることを認識しませんでした。 Windowsでは、同じことを達成するために '_chsize_s'を使う必要があるようです。 –

+0

Windowsでは、対応する関数は 'SetEndOfFile'になります。どちらもシステムハンドルが必要です( 'filebuf'や' FILE * 'ではなく、C++でもCでもない)。 –

1

あなたは移植可能ではありません。異なるシステムには異なる方法がありますが、通常はシステムファイルハンドルでのみ実行されます。 ファイルを短縮する唯一の方法は、別のファイルにコピーし、不要なファイルをコピーしないで、元のファイルを削除して新しいファイルの名前を変更することです。

テキストファイル(バイナリではない)で、ウィンドウが開いている場合、その位置に 0x1Aを書き込むと動作する可能性があります。しかし、Unixでは、 のようなものはありません。

あなたのケースでは、最後を上書きするだけでは十分ではありません。 が悪化し、追加する必要がある場合は、末尾のデータを が上書きするのに十分でない場合、'\0'のように、何か のようにわかりやすく認識できます。私は同様の問題を解決しなければならなかった場合には(正式には、 このようなもの、または0x1Aを書いて、テキストファイルに未定義の動作です。 実際には、それが動作します。)

(、私は を書くの政策を採用しましたレコードの先頭にあるブロックのCRC、読み取り時には、CRCが間違っていたものは無視されました。

関連する問題