C++ fstream 未正确写入对象

c++ fstream not writing to object properly

本文关键字:对象 fstream C++      更新时间:2023-10-16

我有以下代码:

#define _CRT_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include "Person.h"
using namespace std;
int main()
{
// ========================================================================================
// part a - initialiaze 100 records, lastName = "unassigned", firstName = "", age = 0
ofstream outPerson_0("nameage.dat", ios::out | ios::binary);
// exit program if ofstream could not open file
if (!outPerson_0)
{
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
} // end if
Person blankPerson("unassigned", "", 0); // constructor zeros out each data member
// output 100 blank records to file
for (int i = 0; i < 100; ++i)
outPerson_0.write(reinterpret_cast< const char * >(&blankPerson), sizeof(Person));
// ========================================================================================
// part b - input 10 first names and ages and write them to file
string firstName;
string lastName;
int age;
fstream outPerson_1("nameage.dat", ios::in | ios::out | ios::binary);
// exit program if fstream cannot open file
if (!outPerson_1)
{
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
} // end if
// iterate 10 times to get first names and ages
for (int i = 0; i < 10; ++i)
{
// get user input
cout << "Enter last name, first name and age (space separated): ";
// set dummy values in object
std::string s = std::to_string(i);
blankPerson.setLastName(s);
blankPerson.setFirstName(s);
blankPerson.setAge(i);
// seek position in file of user-specified record, using i
auto pos = (i) * sizeof(Person);
outPerson_1.seekp(pos);
// write user-specified information in file
outPerson_1.write(reinterpret_cast<const char *>(&blankPerson), sizeof(Person));
}
// ========================================================================================
// part c - update record with no info
}    

a部分用虚拟值填充了100个对象,并写入文件。 第 b 部分使用迭代器 i 生成的虚拟值更新前 10 个对象。 由于某种奇怪的原因,b部分无法正常工作。 有人能告诉我为什么吗? 结果与我单独运行 a 部分时完全相同。

通常不建议对象直接写入文件,但在这种情况下,您的代码还有其他问题:
ofstreamfstream实例有自己的内部缓冲区,数据将在刷新/同步到底层文件之前写入内部缓冲区。

在退出该计划之前,

  1. Fstream outPerson_1将销毁
  2. 其内部缓冲区将被刷新为文件"nameage.dat">
  3. 上游outPerson_0被销毁
  4. 其内部缓冲区将再次刷新到文件"nameage.dat"
    (至于为什么,那是另一个话题,这里就不说了)

由于outPerson_0中的数据比outPerson_1中的数据多,所以outPerson_1数据被覆盖,然后你就看不到了,如果写入outPerson_1的数据更多,就会观察到它。

您的代码可能有 2 个选项:选项#1:

在写入前 100 人数据后刷新数据

// output 100 blank records to file
for (int i = 0; i < 100; ++i)
outPerson_0.write(reinterpret_cast< const char * >(&blankPerson), sizeof(Person));
outPerson_0.flush();

选项#2:添加ios::
app标志以允许ofstream/fstream将数据附加到文件中

ofstream outPerson_0("nameage.dat", ios::out | ios::binary | ios::app);
fstream outPerson_1("nameage.dat", ios::in | ios::out | ios::binary | ios::app);