I am working on a project to store class objects in a dynamically allocated array. Now instead of users setting objects' values, I am trying to read object's values from a text file. There are 10 objects stored in the file and I want to read 8 objects and then insert them in my dynamic array. This is my class:
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;
}
And my text file looks like this:
Tony
25
Cap
30
Loki & Sylvi
20
...
How can I read these lines into 8 separate objects?
CodePudding user response:
It appears you have not actually compiled the code provided, since there are problems with it.
There are different ways to serialize/deserialize data. Here is one way, which may be sufficient for your needs.
This code allows constructing a Person
from an istream&
. Another way to provide a static class factory function to construct a Person
from an istream&
, which is probably more common.
Once constructed, the Person
can be added to a vector
, which is the dynamic array in 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";
}
CodePudding user response:
If I'd need to save an object to a file, I'd write the raw object to the file:
std::ofstream file("ofile.txt", std::ios::binary, std::ios::trunc);
file.write(&myPerson, (&myPerson)[1]);
And then read the file and cast it to a Person class