0

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.

Community
  • 1
  • 1
JoJo
  • 3
  • 2
  • Did you try searching at all? There are 100s of questions about parsing CSVs. – underscore_d Apr 02 '18 at 13:21
  • Possible duplicate of [How can I read and parse CSV files in C++?](https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c) – underscore_d Apr 02 '18 at 13:22
  • To be fair the discussion there and all the answers seem to involve `boost` which is a bit overkill for a simple CSV parser. – Kristina Apr 02 '18 at 13:36

2 Answers2

0

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.

Kristina
  • 15,859
  • 29
  • 111
  • 181
0

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

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288