1

解决了!非常感谢大家。我的一天已经完成了!(早上好,凌晨 4 点)

我正在尝试用 C++ 编写一个程序,该程序以二进制文件打开一个 .dat 文件,并将前 1840 个十六进制字符替换为另一个 .dat 文件的字符,同时使第一个 .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 点)

4

2 回答 2

3

编辑:

您可以使用以下内容修改您的文件

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,读取剩余数据写入输出文件。

根据“主输入文件”的大小,您可能希望缓冲您的读/写操作。

于 2013-06-28T08:25:04.677 回答
1

My preferred fix, although Matthieu Rouget's fix does indeed work, is to just add ofstreeam::in to the opening of the input file:

ofstream infile ( filename.c_str(), std::ofstream::binary | ofstream::in);

(I had to use c_str() in my build, as glibc in my version doesn't take std::string as input).

I tested this on my local system (it took a while to realize that mod.dat is actually "Mod.dat"!)

It is probably a good idea to also check that the files actually opened, so something like this after ofstream infile line:

if (!infile)
{
cout << "Couldn't open " << filename << endl;
}

and similar for the modfile line.

And since you go through the effort of figuring out what the first part of the modfile size is, I would suggest that you also USE that for the writing of the file.

于 2013-06-28T08:44:36.707 回答