在c++中,将数据插入到文件中的特定位置而不进行覆盖



我有一个以二进制格式存储int的文件。我正在用C++编写一个函数,它获取int数据并将其插入文件中的特定位置。

void AddData(int position, int data);
  • position是必须插入数据的索引
  • data是要插入的int值

代码

void AddData(int position, int data)
{
    fstream os;        
    char buff[4096];
    cnt1 = position;
    cnt2+=(data_cnt-cnt1); // data_cnt is global var to cout the no. of data items 
    os.open("edata.dat", ios::out | ios::in | ios::binary );
    os.seekg(0);                    // start from beg
    os.seekg(cnt1*sizeof(int));     // move to position at which data has to be inserted
    os.read(reinterpret_cast<char*>(buff), cnt2*sizeof(int)); // read rest of file 
    os.seekg(cnt1*sizeof(int));     // move back to previous position
    cout << os.tellg();
    os.write( reinterpret_cast<char*>(&data), sizeof(int) ); //add data
    os.write(reinterpret_cast<char*>(buff), cnt2*sizeof(int)); //write back the read data
    data_cnt++;
}

当函数第一次被调用时,它显示数据项被添加了两次。当函数被第二次调用时,tellg()显示-1。

搞不清楚,怎么了?

老实说,我也看不出哪里出了问题,但请原谅我这么刻板——你的编码风格于事无补!!

在你的例子中,我认为有很多事情是错误的:

  1. 您可以使用全局变量来计算项目数
  2. 您假设剩余部分的字节数不会超过4096
  3. 您的interpret_cast是完全不必要的(写"buff"与写"&buff[0]"相同,并直接给您一个char*)
  4. 您不进行任何检查(例如,位置超出文件末尾?)

老实说,即使你让这个代码工作,每个必须维护它的人都会非常讨厌你。(我很抱歉听起来很刻薄,但我过去不得不维护大量这样的代码,如果某个地方因为你切换到64位操作系统而突然不起作用,那就太可怕了;)

足够的演讲,时间提出建议:

为什么不简单地做以下事情:

  • 将源文件从开始到"位置"(检查位置在文件的边界!)复制到临时文件
  • 将int写入临时文件
  • 将源文件(从位置+1复制到eof)复制到临时文件(从职位+2)
  • 擦除edata.dat,将temp重命名为edata.dat

它更容易、更安全、更清洁,而且可能同样快。最重要的是:如果在比赛结束前出现了问题,你的edata.dat仍然处于稳定、不受破坏的状态。

希望它能帮助

据我所知,cnt2表示插入的int之后的int数,对吧?

在这种情况下,它应该是cnt2 = data_cnt-cnt1,而不是cnt2 += data_cnt-cnt1。您可能应该创建这些局部变量,因为它们不需要在调用之间存储任何内容。

第一次调用该函数时,可能会碰巧得到具有正确值的cnt2。在第二次调用中,它被设置为正确值的两倍(因为您正在递增),因此读取失败,流将进入错误状态。

我不知道为什么数据可能会被添加两次。也许如果你修复了cnt2错误,它可能就开始工作了。

最新更新