我正在尝试打开二进制文件进行写入而不删除内容。但我不想写给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打开文件擦除数据。有人知道答案吗?
答案 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的规范
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;
}`