C++ 类序列化

标签 c++ serialization

我最近了解了 C++ 类的friend关键字以及序列化中的用途,现在我需要一些帮助来让它工作。

我将我的类序列化到文件中没有问题,它工作得很好,但是我很难尝试将此文件读入 vector 容器。我确信我的代码中需要一个循环来逐行读取,但由于该类具有不同的类型,我想我不能使用 std::getline() 并且也许该方法不会使用 istream 方法实现的? 示例输出文件为:

Person 1
2009
1

Person 2
2001
0

我的代码:

class SalesPeople {
    friend ostream &operator<<(ostream &stream, SalesPeople salesppl);
    friend istream &operator>>(istream &stream, SalesPeople &salesppl);

    private:
        string fullname;
        int employeeID;
        int startYear;
        bool status;
};

ostream &operator<<(ostream &stream, SalesPeople salesppl)
{
    stream << salesppl.fullname << endl;
    stream << salesppl.startYear << endl;
    stream << salesppl.status << endl;
    stream << endl;
    return stream;
}

istream &operator>>(istream &stream, SalesPeople &salesppl)
{
    stream >> salesppl.fullname;
    stream >> salesppl.startYear;
    stream >> salesppl.status;
    // not sure how to read that empty extra line here ?
    return stream;
}

// need some help here trying to read the file into a vector<SalesPeople>
SalesPeople employee;
vector<SalesPeople> employees;

ifstream read("employees.dat", ios::in);
if (!read) {
   cerr << "Unable to open input file.\n";
   return 1;
}

// i am pretty sure i need a loop here and should go line by line 
// to read all the records, however the class has different
// types and im not sure how to use the istream method here.

read >> employee;
employees.push_back(employee);

顺便说一句,我知道 Boost 库有一个很棒的序列化类,但是我现在正在尝试使用 STL 库了解序列化如何工作。 预先非常感谢您可以给我的任何帮助,并让我走上正轨!

最佳答案

看来您已经拥有了所需的所有代码!我复制了您的代码并对其进行了一些更改,以循环从文件中读取 SalesPeople。我将在下面添加更改,但由于这是为了您的家庭作业,因此您可能只想在查看代码之前阅读并思考以下提示。

  • 用于阅读销售人员 循环,我建议你采取 看看这个FAQ 。它有一个 几乎正是你的例子 需要。 FAQ 15.4也会有帮助 我相信你。

  • 对于您关于如何处理的问题 读取时多余的空行 从文件中,查看这个 link 。你可以非常简单地 以这种方式提取空格。

  • 正如 jfclavette 所建议的,我会 建议调查 std::getline用于阅读 销售人员的全名,因为您 需要该线上的所有内容合而为一 字符串。

不过,我有一个问题要问你:employeeID 怎么样?我注意到它在您的示例代码中被忽略。是故意的吗?

现在,如果您仍然需要帮助,您可以查看我编写的代码以使其正常工作:

istream &operator>>(istream &stream, SalesPeople &salesppl)
{
    //stream >> salesppl.fullname;
    getline(stream, salesppl.fullname);
    stream >> salesppl.startYear;
    stream >> salesppl.status;
    // not sure how to read that empty extra line here ?
    stream >> ws;
    return stream;
}

while(read >> employee)
{
    // cout << employee; // to verify the input, uncomment this line
    employees.push_back(employee);
}

此外,正如 jfclavette 所建议的,添加一些输入验证可能不是一个坏主意(读取流后检查流状态并验证它是否仍然良好)。尽管出于 FAQ 15.5 中所述的原因,我建议使用 while() 循环。 .

关于C++ 类序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/749757/

相关文章:

javascript - 向 $form.serialize() ajax post 添加额外的数据?

python - 如何使用 Python、pybind11 和 Mingw-w64 构建 setup.py 来编译 C++ 扩展?

c++ - 通过命名成员调用虚拟与地址或引用的区别

android - 让 Kotlin Serializer 与 Retrofit 一起工作

c++ - 以高效的方式创建、访问、存储和加载 boost::bimap

javascript - JS 如何将序列化对象转换为数组?

c++ - 是否可以从 std::bind 对象访问参数?

c++ - Cocos 2D-X 3.2 添加和删除事件监听器

c++ - 我可以为一个构造函数使用一个整数数组,为另一个构造函数使用一个整数吗?

c# - 如何用派生类序列化基类