【问题标题】:Writing vector of objects to file将对象向量写入文件
【发布时间】:2016-03-14 10:51:10
【问题描述】:

如何写入一个包含多个指向文件的字符指针的对象并读回?

class Student {
        public:
                char* name;
                char* age;
                int size;

                Student(char* _name, char* _age) {
                        name = _name;
                        age = _age;
                        size = 0;
                        size = strlen(_name) + strlen(_age);
                }
};

我有一个 Student 对象的向量数组 (vector<Student*>)。如何将此向量写入文件,然后再读回?

有人可以帮忙吗?我们可以在没有boost::serialization 的帮助下做到这一点吗?

【问题讨论】:

  • 你当然可以自己实现序列化。 boost::serialization 不是由魔法精灵尘制成的;这只是人们编写的代码。
  • 只要你的Student类是一个POD,你就可以遍历向量并将student结构作为二进制流写入文件,然后继续附加到文件中。在阅读时,您可以从文件中读取 sizeof(Student),将其转换为 Student 结构直到 EOF。
  • @Arunmu 不是一个好主意。如您所见,它包含指针。
  • @molbdnilo 当然他会取消引用它:)。他不需要序列化向量,只需序列化数据。
  • @Arunmu 你有没有看过Student提供的定义?

标签: c++ file vector stl fwrite


【解决方案1】:

首先更喜欢std::string 而不是char*。你不再需要那个尺寸了。也更喜欢在构造函数中初始化而不是在构造函数主体中分配值:

class Student {
    public:
        std::string name;
        std::string age;

        Student(const std::string& _name, const std::string& _age) : 
            name{_name}, age{_age}
        {};

        auto size() const -> size_t {
            return name.size() + age.size();
        };
};

回到你的问题。在尝试存储复杂结构之前,您必须定义格式。在这种情况下,我选择了一个简单的 CSV,用分​​号作为字段分隔符,没有引号。

void writeStudents(std::ostream& o, const std::vector<Student*>& students) {
    for(auto s: students) {
        o << s->name << ';' << s->age << '\n';
    }
}
void writeStudents(std::ostream&& o, const std::vector<Student*>& students) {
    writeStudents(o, students);
}

现在您可以使用 `std::ofstream` 生成该 csv:

writeStudents(std::ofstream{"myFilename"}, students);

要读回它,你必须解析你之前定义的格式:

auto readStudents(std::istream& i) -> std::vector<Student*> {
    auto students = std::vector<Student*>;
    auto line = std::string{};

    while( std::getline(i, line) ) {
        auto pos = line.find_first_of(';');
        students.push_back(new Student{std::string{line, 0, pos},
                                       std::string{line, pos+1}});
    }

    return students;
}
auto readStudents(std::istream&& i) -> std::vector<Student*> {
    return readStudents(i);
}

现在您可以使用std::ifstream 阅读您的文件:

auto students = readStudents(std::ifstream{"myFilename"});

注意:此答案中的所有代码均未经测试。当然,要小心错误。我还为你留下了错误处理,因为我不想用那种噪音污染答案。

顺便说一句:您如何确保正确管理学生的记忆?考虑使用std::unique_ptr&lt;&gt;std::shared_ptr&lt;&gt; 而不是原始指针。

【讨论】:

  • 你必须临时通过 const 引用,否则它不会编译。
  • @Arunmu 不错。在这种情况下,流当然不能是 const。我将我的分析器更改为流变量而不是临时变量。
  • 太糟糕了 ostream 无法移动
  • @Arunmu 哦,你是对的。 istreamostream 可以移动。所以我们可以拥有更漂亮的API。谢谢。
  • 不,我想说不能移动 ostream。 stackoverflow.com/questions/20774587/…
猜你喜欢
  • 2023-03-06
  • 2019-10-27
  • 2020-12-17
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多