将数据插入文件中的特定位置而不用c ++中的覆盖

时间:2012-08-05 03:30:01

标签: c++ file-io

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

想不通,什么出错了?

2 个答案:

答案 0 :(得分:0)

老实说,我也看不出有什么问题,但是 - 请原谅我这样的困难 - 你的编码风格无济于事!!

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

  1. 您使用全局变量来计算项目数。
  2. 您假设剩余部分
  3. 中的字节数不会超过4096个字节
  4. 你的reinterpret_cast是完全没必要的(写'buff'和写'&amp; buff [0]'一样,直接给你一个char *)
  5. 您不做任何检查(例如,位于文件末尾的位置 ?)
  6. 老实说,即使你使这个代码工作,每个必须维护它的人都会非常讨厌你。 (我很遗憾听起来很卑鄙,但我过去必须保留大量此类代码,如果因为你切换到64位操作系统,某些东西突然不起作用,那就是nighmare;)

    足够讲课,有时间提出建议:

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

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

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

    希望有所帮助

答案 1 :(得分:0)

据我所知,cnt2意味着在插入int之后代表的数量,对吗?

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

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

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