简体   繁体   中英

How to stream a comma separated txt file to a class object?

How do I stream a line of comma separated txt file to an object that contain first name, last name and age variables? I want to overload the >> operator to do such operations.

std::istream& operator>>(std::istream& file, PersonData& obj) {
    std::string line, firstName, lastName, age;

    while (std::getline(file, line)) {
        std::stringstream ss(line);
        std::getline(ss,firstName,',');
        std::getline(ss,lastName,',');
        std::getline(ss, age,',');
        firstName >> obj.firstName;
        lastName >> obj.lastName;
        std::stoi(age) >> obj.age;
    }

    return file; 
}

Your operator>> should read a single entry from the file.

If you have a class

struct Person {
    std::string first_name;
    std::string last_name;
    unsigned age;
};

You can use in/output operators:

std::ostream& operator<<(std::ostream& out,const Person& p) {
    out << p.first_name << ", " << p.last_name << ", " << p.age;
    return out;
}

std::istream& operator>>(std::istream& in,Person& p){
    const auto comma = ',';
    std::getline(in,p.first_name,comma);
    std::getline(in,p.last_name,comma);
    std::string temp;
    std::getline(in,temp);
    p.age = std::stoi(temp);
    return in;
}

And then extract one Person at a time from the file:

int main() {
    std::stringstream ss{"Peter, Fish, 42\nLaura, Peterson, 105"};
    Person p1,p2;
    ss >> p1 >> p2;
    std::cout << p1 << "\n" << p2;
};

Output:

Peter,  Fish, 42
Laura,  Peterson, 105

Live example

To read all entries from a file you can use a vector and a loop:

std::vector<Person> persons;
Person entry;
while(stream >> entry) persons.push_back(entry);

PS: I missed to remove leading blanks from the names. I'll leave that to you ;)

Here's a stencil for your class:

class My_Class
{
    public:  
      friend std::istream& operator>>(std::istream& input, My_Class& mc);
    private:
    // members go here.
};


std::istream& operator>>(std::istream& input, My_Class& mc)
{
  // Insert code to read comma separated values here.
  return input;
}

The above allows you to stream input to your class:

My_Class mc;
std::vector<My_Class> database;
while (input_file >> mc)
{
    database.push_back(mc);
}

Edit 1: Reading CSV
Based on the code you posted, I believe this is what you want:

std::istream& operator>>(std::istream& input, My_Class& mc)
{
    std::getline(input, mc.firstName,',');
    std::getline(input, mc.lastName,',');
    input >> mc.age;
    // Ignore till the end of the line:
    input.ignore(10000, '\n');
    return input;
}

Editing your question with a sample of the input file will allow readers to confirm or deny the content of the function.

john-wick.txt

John,Wick,50

main.cpp

#include <iostream>
#include <fstream>

struct PersonData {
    string firstname;
    string lastname;
    int age;

    friend std::istream& operator>>(std::istream& in, PersonData& obj) {
        char comma;
        in >> obj.firstname >> comma >> obj.lastname >> comma >> obj.age;
        return in;
    }
}

int main(int argc, char *argv[]) {
    std::ifstream file("john-wick.txt");

    PersonData john;
    file >> john;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM