2011-06-21 17 views
11

コンテンツを消去せずに書き込み用にバイナリファイルを開こうとしています。しかし、私はeofに書きたいとは思わない。私はファイル内の特定の位置に書きたい。既存のバイナリファイルの中央に書き込むC++

はここリッテ例です:

ofstream out("test.txt", ios::binary | ios::app); 
for(int i = 0; i < 100; i++) 
    out.put('_'); 
out.write("Hallo", 5); 
out.close(); 

ofstream out2("test.txt", ios::binary | ios::app); 
out2.seekp(10); 
out2.write("Welt", 4); 
out2.close(); 

アプリを使用している場合、動作しません求めます。アプリオープニングファイルを使用していない場合、データが消去されます。誰かが答えを知っていますか?

答えて

10

あなたはオフセットと方向、これはあなたのケース(すなわちios_base::beg)でファイルの初めできることを提供することを可能にするseekpの2番目のオーバーロードを、してみてください。もちろんこれはあなたが何をしているのかを知っていることを前提としています。あなたがしたいのは、既存の文字数を上書きすることだけです。

編集:ここでは、完全に例を働いている:

#include <iostream> 
#include <fstream> 

using namespace std; 
int main() 
{ 
    { 
    ofstream out("test.txt", ios::binary); 
    for(int i = 0; i < 100; i++) 
     out.put('_'); 
    out.write("Hallo", 5); 
    } 

    { 
    fstream out2("test.txt", ios::binary | ios::out | ios::in); 
    out2.seekp(10, ios::beg); 
    out2.write("Welt", 4); 
    } 
} 
+0

私はout2.seekp(10、ios_base :: beg);を試しました。それは何も変わらない。 –

+0

ios :: trunc – crashmstr

+0

@crashmstrを指定しない限り、ファイルを消去するべきではありません。私は私のコメントを削除しています。 –

5

途中から魔法のようにファイルを拡張することはできません。おそらく、新しいファイルに書き込むのが最も簡単です。最初に最初のセグメントをコピーしてから、新しいデータを書き込み、残りのセグメントをコピーします。すべて完了したら、元のファイルを上書きすることができます。

+0

私はファイルを途中で伸ばしたくありません。私は初期値を上書きしたい! –

+0

@ジョニー:あなたの質問で言ったことではありません。あなたは「内容を消去することなく」と言った。さもなければ、それは自明であり、書き込みのためだけに開いて(「追加」せずに)、最初に探して書きます。 –

+0

私は最初に書きたいとは思わない。私はファイルのどこかに書きたいと思う。問題は、ファイルを再度開いてコンテンツを消去することです。 例: 最初のファイル: ______________________操作後のファイル:______Bla_______ –

5

イオス::アプリで開く、それはあなただけで、既存のファイルに添付することが起こった新しいファイルを開いたかのようです:あなたは、既存のファイルにアクセスできません。私はKerrekの回答のようにするので、私は確信していませんが、実際に試してみたい場合は、おそらく "ios :: in ios :: out"で開く必要があります、fopen( "test。 txt "、" rw ")。

またはcrashmstrが指摘しているように:ios :: outで十分でしょう。ここ

fstream::open

イオス:: fstreamのアプリの仕様によると

+4

あなたは 'ios :: out'と' ios :: in'の両方が必要です。そうでなければ、単純にmethinksを上書きします.. – Nim

+0

'ios :: out'だけでlinux上で次のような種類のオープンコール:O_WRONLY | O_CREAT | O_TRUNC、 'ios :: out | ios :: in'は、O_TRUNCなしでO_RDWR呼び出しを行います。 – daminetreg

2

「は、各出力操作の前にストリームの最後にストリームの位置インジケータを設定します。」だからios :: appは、少なくとも私のために、どのような並べ替えのシークが失敗する、交換のために動作しません。

ios :: outを使用するだけで、サイズのみを保持するファイルの内容が消去されます。基本的にはファイルをごみ箱にします。

ios :: in | ios :: outは私の唯一の働きとして判明しました。

0

作業コード:このコードは、cout.exeで文字列(OLD-STRING)を検索し、新しい文字列(NEW-STRING)で置き換えます。

`#include "stdafx.h" 
#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 

int main(int argc, char *argv[]) 
{ 
    fstream ifs; 
    ifs.open ("C:\\Users\\user\\Desktop\\cout.exe", fstream::binary | fstream::in | fstream::out); 

    std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); 

    size_t pos = str.find("OLD-STRING"); 

    if (pos != string::npos) 
    { 
    cout << "string found at position: " << int(pos) << endl; 

    ifs.seekp(pos); 

    ifs.write("NEW-STRING", 10); 

    } 
    else 
    { 
    cout << "could not find string" << endl; 
    } 

    if (ifs.is_open()) 
    ifs.close(); 

    return 0; 
}` 
関連する問題