写入现有二进制文件c ++的中间

时间:2011-06-21 15:16:37

标签: c++ file stream append seek

我正在尝试打开二进制文件进行写入而不删除内容。但我不想写给eof。我想写一个文件中的特定位置。

这是一个小例子:

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();

如果使用app,搜索不起作用。如果不使用app打开文件擦除数据。有人知道答案吗?

5 个答案:

答案 0 :(得分:11)

尝试seekp的第二次重载,它允许您提供偏移量和方向,这可能是您的情况下的文件开头(即ios_base::beg)。这当然假设您知道自己在做什么,而您想要做的就是覆盖现有的字符数。

编辑:这是完全有效的例子:

#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);
  }
}

答案 1 :(得分:5)

你无法从中间神奇地扩展文件。也许最容易写入新文件:首先复制初始段,然后写入新数据,然后复制剩余段。完成所有操作后,您可以覆盖原始文件。

答案 2 :(得分:5)

使用 ios :: app 打开时,就好像您打开一个恰好附加到现有文件的新文件:您无法访问现有文件。我不确定,因为我会像Kerrek的回答一样,但是如果你真的想尝试,你可能必须打开“ ios :: in | ios :: out ”,类似于fopen(“test.txt”,“rw”)。

或者正如crashmstr所指出的那样: ios :: out 可能就够了。

答案 3 :(得分:2)

根据fstream的规范

fstream::open

ios :: app“在每次输出操作之前将流的位置指示符设置为流的末尾。”因此,至少对我而言,ios :: app不能替换,任何类型的搜索失败。

只使用ios :: out会删除仅保留大小的文件内容,基本上将文件变为垃圾。

ios :: in | ios :: out对我来说是唯一有用的东西。

答案 4 :(得分: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;
}`