【问题标题】:How do we read from file and store it into different objects in c++?我们如何从文件中读取并将其存储到 c++ 中的不同对象中?
【发布时间】:2021-11-23 10:35:46
【问题描述】:

我正在开发一个将类对象存储在动态分配数组中的项目。 现在,我尝试从文本文件中读取对象的值,而不是用户设置对象的值。文件中存储了 10 个对象,我想读取 8 个对象,然后将它们插入我的动态数组中。这是我的课:

class Person {
private:
    std::string name;
    double age;

public:
    // Constructor
    Stock(const std::string& name = "", double age = 0)
    {
        this->name = name;
        this->age = age;
    }

    // copy constructor
    Stock(const Stock& s)
    {
        this->name = s.name;
        this->age = s.age;
    }

    // Display function
    void display() const
    {
        std::cout << "Name is " << name << ", "
        << "Age is " << age << ".\n";
    }

    // get functions
    std::string getName() const
    {
        return name;
    }
    double getAge() const
    {
        return age;
    }

我的文本文件如下所示:

Tony
25
Cap 
30
Loki & Sylvi
20
...

如何将这些行读入 8 个单独的对象?

【问题讨论】:

  • 认真的吗? Person 带有 Stock 构造函数的类?
  • 一旦你修复了你的构造函数,你将需要一个可增长的数组,因为你不(或者可能不应该)提前知道你的程序需要多少记录。查看std::vector。然后只需读取每个对象的两行输入,将看起来像数字的字符串转换为实际数字,然后构造您的对象。

标签: c++ class object file-io


【解决方案1】:

如果我需要将对象保存到文件中,我会将原始对象写入文件:

std::ofstream file("ofile.txt", std::ios::binary, std::ios::trunc);
file.write(&myPerson, (&myPerson)[1]);

然后读取文件并将其转换为 Person 类。

【讨论】:

  • name 成员的哪一部分将使用这种机制写入?
  • 此代码将对象的精确原始副本保存到二进制文件中。
  • std::string 的精确原始副本只不过是一个指针和一个计数。将指针写入文件不会存储字符串内容。
  • 你复制了指针,而不是它指向的东西
  • 如果你只存储了一个指向一块内存的指针,而下次运行程序时几乎肯定不会包含相同的数据,你希望如何恢复字符串对象?
【解决方案2】:

您似乎还没有真正编译提供的代码,因为它存在问题。

序列化/反序列化数据有不同的方法。这是一种方法,可能足以满足您的需求。

此代码允许从istream&amp; 构造Person。另一种提供静态类的方法工厂函数istream&amp;构造Person,这可能更常见。

构造完成后,Person 可以添加到 vector,这是 C++ 中的动态数组。

#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

using std::cout;
using std::getline;
using std::istream;
using std::istringstream;
using std::move;
using std::ostream;
using std::runtime_error;
using std::string;
using std::vector;

namespace {

char const* data =
R"(Tony
25
Cap 
30
Loki & Sylvi
20
Bob 1
20
Bob 2
30
Bob 3
40
Bob 4
50
Bob 5
60
Bob 6
70
Bob 7
80
)";

auto get_string(istream& in) -> string {
    string result;
    if (getline(in, result)) return result;
    throw runtime_error("get_string");
}

auto get_double(istream& in) -> double {
    string line;
    if (!getline(in, line))
        throw runtime_error("get_double");

    istringstream ss(line);
    double result;
    if (!(ss >> result))
        throw runtime_error("get_double");

    return result;
}

class Person final {
    string _name;
    double _age;

public:
    Person(string name_ = "", double age_ = 0) : _name{move(name_)}, _age{age_} { }
    Person(Person const& s) : _name{s._name}, _age{s._age} { }
    Person(istream& in) : _name{get_string(in)}, _age{get_double(in)} { }

    void print(ostream& out) const {
        out << "Name is " << _name << ", " << "Age is " << _age << ".";
    }

    auto name() const -> string { return _name; }
    auto age() const -> double { return _age; }
};

auto operator<<(ostream& out, Person const& p) -> ostream& {
    p.print(out);
    return out;
}

auto operator<<(ostream& out, vector<Person> const& v) -> ostream& {
    for (auto&& p : v) {
        out << p << "\n";
    }
    return out;
}

} // anon

int main() {
    istringstream ss(data);
    auto tony = Person(ss);
    auto cap = Person(ss);
    auto loki_sylvi = Person(ss);
    cout << tony << "\n";
    cout << cap << "\n";
    cout << loki_sylvi << "\n";

    vector<Person> peeps;
    peeps.emplace_back(ss);
    peeps.emplace_back(ss);
    peeps.emplace_back(ss);
    cout << peeps << "\n";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2021-07-10
    相关资源
    最近更新 更多