c ++ fstream没有正确写入对象

时间:2018-03-08 00:07:13

标签: c++ fstream ofstream

我有以下代码:

#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
}    

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

1 个答案:

答案 0 :(得分:0)

通常不建议将对象直接写入文件,但只是大小写,您的代码还有其他问题:
ofstream fstream 实例拥有自己的内部缓冲区,在刷新/同步到基础文件之前,数据将被写入内部缓冲区。

退出计划之前,

  1. fstream outPerson_1 将被销毁
  2. 其内部缓冲区将刷新到文件&#34; nameage.dat&#34;
  3. ofstream outPerson_0 被销毁
  4. 将其内部缓冲区刷新到文件&#34; nameage.dat&#34;再次
    (至于为什么,这是另一个话题,不要在这里谈谈)
  5. 由于outPerson_0中的数据多于outPerson_1中的数据,因此outPerson_1数据会被覆盖,然后您无法看到它,如果您将更多数据写入outPerson_1,您将会观察到它。

    您的代码可能有两种选择:
    选项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);