我有一个以二进制格式存储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。
搞不清楚,怎么了?
老实说,我也看不出哪里出了问题,但请原谅我这么刻板——你的编码风格于事无补!!
在你的例子中,我认为有很多事情是错误的:
- 您可以使用全局变量来计算项目数
- 您假设剩余部分的字节数不会超过4096
- 您的interpret_cast是完全不必要的(写"buff"与写"&buff[0]"相同,并直接给您一个char*)
- 您不进行任何检查(例如,位置超出文件末尾?)
老实说,即使你让这个代码工作,每个必须维护它的人都会非常讨厌你。(我很抱歉听起来很刻薄,但我过去不得不维护大量这样的代码,如果某个地方因为你切换到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错误,它可能就开始工作了。