简体   繁体   中英

How to set class objects from vector of string in c++

These are the data in my Login.csv file:

ID,Name,Password,Gender

1,Liam,1234,M

2,Janice,0000,F

So probably I'll use class & objects to create login details, and write it into the file. After that I will split the csv from file into a vector of strings, from there how do I load back the details to objects of class.

This is my code of splitting the csv from file:

int _tmain(int argc, _TCHAR* argv[])
{    
    string line;
    ifstream fin("users.csv");

    while (getline(fin, line)){
        vector<string> token;
        split(line, ',', token);

        for (int i = 0; i < token.size(); i++){
            cout << token[i] << " ";

            //////////// <<here>>
        }
        cout << endl;
    }

    system("pause");
    return 0;
}

void split(const string& s, char c, vector<string>& v) {

    string::size_type i = 0;
    string::size_type j = s.find(c);

    while (j != string::npos) {
        v.push_back(s.substr(i, j - i));
        i = ++j;
        j = s.find(c, j);

        if (j == string::npos)
            v.push_back(s.substr(i, s.length()));
    }
}

I was thinking how can I set the splitted strings from the string vector to a vector of objects, something like this: (to put in the << here >> section i commented in above)

vector<Login>loginVector;

//all the objects below should set from string vector (token)
loginVector[i].setID(); //i=0, id=1, name=Liam, password=1234, gender=M
loginVector[i].setName();
loginVector[i].setPassword();
loginVector[i].setGender();

loginVector[i].setID(); //i=1, id=2, name=Janice, password=0000, gender=M
loginVector[i].setName();
loginVector[i].setPassword();
loginVector[i].setGender();

Thank you.

Implement your Login object and populate it in the loop.

struct Login {
    enum Gender {
        Male,
        Female
    };

    int Id;
    std::string Name;
    std::string Password;

    /* you should probably use a constructor */
};

/* to construct your vector */

int I = 0;
while(I < token.size()) {
    /* in your iterator */
    Login& LO = loginVector.emplace_back(Login{});

    LO.Id = std::stoi(token[++I]);
    LO.Name = token[++I];

    /* etc...*/
}

Note that this assumes your CSV is well formed, up to you to implement all the checking and make sure you handle corner cases like possible errors from stoi , blank rows or missing columns.

Also, don't do system("pause"); , you're executing a shell to sleep for you, which has massive overhead compared to just using sleep which does literally the same thing except in a far more direct way.

I personally would implement this by adding an extraction operator for your class. You'll have to friend the extraction operator because it must be defined externally to your class, since it's actually operating on the istream and not on your class, so something like this should be defined in your class:

friend istream& operator>> (istream& lhs, Login& rhs);

Depending on how your variables are named your extraction operator should look something like this:

istream& operator>> (istream& lhs, Login& rhs) {
    char gender;

    lhs >> rhs.id;
    lhs.ignore(numeric_limits<streamsize>::max(), ',');
    getline(lhs, rhs.name, ',');
    getline(lhs, rhs.password, ',');
    lhs >> ws;
    lhs.get(gender);
    rhs.isMale = gender == 'm' || gender == 'M';

    return lhs;
}

Live Example

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