3

\n各追加文字がファイルに追加された後にのみ追加できる内部ファイルがあります。ただし、理論的には、ファイルへの追加に失敗して破損する可能性があります。そのため、ファイルを開くたびに、最後の 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() から最後まで削除する必要があります。

どうやってやるの?

4

2 に答える 2

1

ポータブルにはできません。システムが異なれば、これを行う方法も異なりますが、通常はシステム ファイル ハンドルに対してのみです。ファイルを短縮する唯一の保証された方法は、不要なものをコピーするのではなく、別のファイルにコピーし、元のファイルを削除して新しいファイルの名前を変更することです。

テキスト ファイル (バイナリではない) で、Windows を使用している場合は、その位置に 0x1A を書き込むとうまくいく可能性があります。ただし、Unix では同様のものはありません。

あなたの場合、最後を上書きするだけでは十分ではありません。さらに悪化し、末尾のデータを上書きするのに追加する必要があるものでは不十分な場合は、無害で簡単に認識できるもので上書きしてみてください'\0'。(正式には、このようなもの、または 0x1A をテキスト ファイルに書き込むことは、未定義の動作です。実際には、動作します。)

(同様の問題を解決しなければならなかったとき、レコードの先頭にブロックの CRC を書き込むというポリシーを採用しました。読み取り時に、CRC が間違っているものはすべて無視しました。)

于 2012-04-20T10:09:54.830 に答える
1

これを行う移植可能な方法はありません (完全な説明については、James Kanze のより良い回答を参照してください)。

POSIX システムを使用している場合は、ftruncate(こちらを参照) を使用して、ファイルの長さを特定の長さに設定できます。C++ に相当するものを知りません (詳細については、この質問を参照してください)

于 2012-04-20T09:49:52.887 に答える