1

我有一个以二进制格式存储整数的文件。我正在用 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。

想不通,怎么回事?

4

2 回答 2

0

老实说,我也看不出有什么问题,但是-请原谅我这么直截了当-您的编码风格无济于事!

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

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

老实说,即使您使此代码正常工作,每个必须维护它的人都会非常讨厌您。(我很抱歉听起来很刻薄,但我过去不得不维护大量这样的代码,如果因为您切换到 64 位操作系统而突然无法工作,那将是一个噩梦;))

讲够了,有时间提建议:

为什么不简单地执行以下操作:

  • 将源文件从开头复制到“位置”(并检查位置是否在文件的边界内!)到临时文件。
  • 将您的 int 写入您的临时文件
  • 复制源文件(从位置+1到eof),到临时文件(从位置+2)
  • 擦除edata.dat,将temp重命名为edata.dat

它更容易、更安全、更清洁并且可能同样快速。最重要的是:如果在结束之前发生错误,您的 edata.dat 仍然处于稳定、未损坏的状态。

希望能帮助到你

于 2012-08-05T04:15:55.373 回答
0

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

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

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

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

于 2012-08-05T05:15:24.633 回答