已解决!非常感谢大家。我的一天已经过去了!(早上4点)
我试图用C++编写一个程序,打开一个二进制.dat文件,用另一个.dat文件的十六进制字符替换前1840个十六进制字符,同时保持第一个.dat的其余十六进制值不变。我今天花了大约12个小时在这方面,但收效甚微。我是一名初级程序员,我已经学习了一学期的c++课程,但我们没有进入流媒体。
(它打开一个文件和所有内容,但在添加新值后删除所有内容)
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>
#include <cstring>
using namespace std;
int main (){
string filename;
long size;
char* memblock;
cout << " Enter a file to be modded by Mod.dat ";
cin >> filename;
ofstream infile ( filename ,std::ofstream::binary);
//filename: the file that will be opened and changed)
ifstream modFile ("Mod.dat", ifstream::binary);
// (mod.dat is the file that i get the first 1840 hex values from)
modFile.seekg (0,modFile.end);
size = modFile.tellg();
memblock = new char [size];
modFile.seekg (0, ios::beg);
modFile.read (memblock, size);
infile.write(memblock, 1840);
modFile.close();
infile.close();
cout << endl;
return 0;
}
任何帮助都将不胜感激,我希望有一些简单的方法可以做到这一点。
解决了!非常感谢大家。我的一天已经过去了!(早上4点)
编辑:
你可以用类似的东西修改你的文件
std::fstream s(my_file_path, std::ios_base::binary);
s.seekp(position_of_data_to_overwrite, std::ios_base::beg);
s.write(my_data, size_of_data_to_overwrite);
std::fstream
不会像std::ofstream
那样截断输入文件。
另一种解决方案是不使用同一个文件进行读取和写入。使用三个文件:
- 一个用于输出文件
- 一个用于第一个输入文件
- 一个用于第二个输入文件
fstream infile ( filename ,std::ofstream::binary);
不保留原始文件的内容。你写的所有内容都会擦除文件的内容。
因此,您应该:
- 打开输出文件
- 打开"Mod"文件,从第一个文件中读取前1840个字节,将它们写入输出文件
- 打开"主输入文件"文件,将光标移动到1840,读取剩余数据并将其写入输出文件
根据"主输入文件"的大小,您可能需要缓冲您的读/写操作。
尽管Matthieu Rouget的修复确实有效,但我的首选修复方法是将ofstreeam::in
添加到输入文件的开头:
ofstream infile ( filename.c_str(), std::ofstream::binary | ofstream::in);
(我不得不在构建中使用c_str(),因为我的版本中的glibc不接受std::string作为输入)。
我在本地系统上测试了这个(花了一段时间才意识到mod.dat实际上是"mod.dat"!)
检查文件是否真的打开可能是个好主意,所以在ofstream infile
行之后会出现类似的情况:
if (!infile)
{
cout << "Couldn't open " << filename << endl;
}
对于modfile行也是类似的。
由于您已经努力弄清楚modfile
大小的第一部分是什么,我建议您也使用它来编写文件。