【问题标题】:How to set class objects from vector of string in c++如何在c ++中从字符串向量设置类对象
【发布时间】:2018-04-02 13:12:41
【问题描述】:

这些是我的 Login.csv 文件中的数据:

ID、姓名、密码、性别

1,利亚姆,1234,M

2,珍妮丝,0000,F

所以我可能会使用类和对象来创建登录详细信息,并将其写入文件中。之后,我会将文件中的 csv 拆分为字符串向量,然后如何将详细信息加载回类对象。

这是我从文件中拆分 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()));
    }
}

我在想如何将拆分的字符串从字符串向量设置为对象向量,如下所示:(放入我在上面评论的 > 部分)

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();

谢谢。

【问题讨论】:

  • 您是否尝试过搜索?有 100 多个关于解析 CSV 的问题。
  • 公平地说,那里的讨论和所有答案似乎都涉及boost,这对于简单的 CSV 解析器来说有点矫枉过正。

标签: c++ csv vector strsplit


【解决方案1】:

实现您的 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...*/
}

请注意,这假设您的 CSV 格式正确,由您来实施所有检查并确保您处理极端情况,例如来自 stoi 的可能错误、空白行或缺失列。

另外,不要使用system("pause");,您正在执行一个 shell 来为您休眠,与仅使用 sleep 相比,它具有巨大的开销,除了以更直接的方式之外,它实际上做了同样的事情。

【讨论】:

    【解决方案2】:

    我个人会通过为您的班级添加extraction operator 来实现这一点。 您必须 friend 提取运算符,因为它必须在您的类外部定义,因为它实际上是在 istream 而不是您的类上操作,因此应该在您的类中定义类似的内容:

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

    根据变量的命名方式,提取运算符应如下所示:

    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

    【讨论】:

      猜你喜欢
      • 2011-05-28
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2014-05-08
      相关资源
      最近更新 更多