简体   繁体   English

如何在C ++中从字符串向量设置类对象

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

These are the data in my Login.csv file: 这些是我的Login.csv文件中的数据:

ID,Name,Password,Gender 身份证,姓名,密码,性别

1,Liam,1234,M 1,利亚姆,1234,M

2,Janice,0000,F 2,詹妮丝,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. 之后,我将csv从文件拆分为字符串向量,然后从那里将细节加载回类对象。

This is my code of splitting the csv from file: 这是我从文件中拆分csv的代码:

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. 实现您的Login对象并在循环中填充它。

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. 请注意,这假设您的CSV格式正确,可以由您实施所有检查,并确保您处理诸如stoi ,空白行或缺少列的可能错误之类的stoi情况。

Also, don't do system("pause"); 另外,不要执行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. ,您正在执行一个shell来为您睡眠,与仅使用sleep实际上会做同样的事情相比,这有很多开销,只是以更直接的方式。

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而不是在您的类上进行操作,因此应在类中定义以下内容:

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 现场例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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