C ++按行读取逗号分隔文件[其中一个部分为mm/dd/yyyy],安全地放入结构中

C++ reading in a comma delimited file[with one section as mm/dd/yyyy] by line, placing into a struct securely

为了扩展标题,我正在阅读一个文件 line-by-line,它显示为:

FirstName,LastName,mm/dd/yyyy,SSN,Role,Salary,Zip,Phone

我有刚刚编写的这段代码,但是由于我使用的是 std::string 而不是 char[],所以将它放入我的结构中时遇到了一些问题。我想在以后继续使用 std::string。另外,请原谅我有一段时间没有在 c/c++ 中编写任何语法错误。我也读过 the most elegant way to iterate to words of a string 但我仍然对如何使用日期格式中涉及的斜杠来做到这一点感到困惑。 SSN 和 Salary 是结构的私有成员,将被推入一个向量供以后使用。我如何使用 C++ 库执行此操作?老实说,istringstream 让我感到困惑,因为它们直接在其结构中包含某种类型的解析器。这真的是完成我想要做的事情的最佳方式吗?

char stringData[150]; //line to be read in 
while(fgets(stringData, 150, infile) != NULL) {
    if( currentLine == 1) {
        fgets(stringData, 150, infile); //get column names | trash
    }
    else {
        lineSize = sscanf(stringData, "%[^,],%[^,],%d/%d/%d,%d,%[^,],%lf,%[^,],%s", temp.firstName,temp.lastName,
                       &temp.birthMonth,&temp.birthDay,&temp.birthYear, 
                       &tempSSN, temp.role, &tempSalary, temp.zip,
                       temp.phoneNum);

        if(lineSize != 10) { //error message due to a row being incorrect
            cerr << "/* ERROR: WRONG FORMAT OF INPUT(TOO FEW OR TOO MANY ARGUMENTS) ON LINE: */" << currentLine << '\n';
            exit(1);
        }

        temp.setSSN(tempSSN);
        temp.setSalary(tempSalary);
        vector.push_back(temp);//push Employee temp into the vector and repeat loop
    }
    currentLine++
}

TL;DR:使用 C++ 库执行此操作的最简单方法是什么?

正如 Sam Varshavchik 已经提到的,最简单的方法是用 , 分隔输入,然后再次用 / 分隔输入。

感谢 this famous question 我使用以下方法拆分字符串:

template<typename Out>
void split(const std::string &s, char delim, Out result)
{
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim))
    {
        *(result++) = item;
    }
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    split(s, delim, std::back_inserter(elems));
    return elems;
}

假设这是您的结构:

struct info
{
    std::string firstName;
    std::string lastName;
    std::string birthMonth;
    std::string birthDay;
    std::string birthYear;
    std::string tempSSN;
    std::string role;
    std::string tempSalary;
    std::string zip;
    std::string phoneNum;

};

我会像这样实现您需要的功能:

void parser(std::string fileName, std::vector<info> &inf)
{
    std::string line;
    std::ifstream infile(fileName);
    int index = inf.size();
    while(std::getline(infile, line))
    {
        inf.push_back({});
        std::vector<std::string> comma_seprated_vec = split(line, ',');
        inf.at(index).firstName = comma_seprated_vec.at(0);
        inf.at(index).lastName = comma_seprated_vec.at(1);
        inf.at(index).tempSSN = comma_seprated_vec.at(3);
        inf.at(index).role = comma_seprated_vec.at(4);
        inf.at(index).tempSalary = comma_seprated_vec.at(5);
        inf.at(index).zip = comma_seprated_vec.at(6);
        inf.at(index).phoneNum = comma_seprated_vec.at(7);
        std::vector<std::string> slash_seprated_vec = split(comma_seprated_vec.at(2), '/');
        inf.at(index).birthMonth = slash_seprated_vec.at(0);
        inf.at(index).birthDay = slash_seprated_vec.at(1);
        inf.at(index).birthYear = slash_seprated_vec.at(2);
        ++index;
    }
}

然后你就可以这样使用了:

int main()
{
    std::vector<info> information;
    parser("some file", information);

    return 0;
}

好了,您的信息显示在 information 变量中。