用c ++读取CSV文件中的两列

时间:2015-05-12 04:05:19

标签: c++ csv

我有一个两列形式的CSV文件:名称,年龄

要阅读和存储信息,我这样做了

struct person
{
    string name;
    int age;
}
person record[10];
ifstream read("....file.csv");

然而,当我做的时候

read >> record[0].name;
read.get();
read >> record[0].age;

读取>>名称给了我整行,而不仅仅是名称。我怎么可能避免这个问题,以便我可以将整数读入年龄?

谢谢!

3 个答案:

答案 0 :(得分:5)

您可以先使用std:getline阅读整行,然后通过std::istringstream(必须#include <sstream>)解析,例如

std::string line;
while (std::getline(read, line)) // read whole line into line
{
    std::istringstream iss(line); // string stream
    std::getline(iss, record[0].name, ','); // read first part up to comma, ignore the comma
    iss >> record[0].age; // read the second part
}

以下是一个完整的常规示例,用于标记CSV文件Live on Ideone

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

int main()
{
    // in your case you'll have a file
    // std::ifstream ifile("input.txt");
    std::stringstream ifile("User1, 21, 70\nUser2, 25,68"); 

    std::string line; // we read the full line here
    while (std::getline(ifile, line)) // read the current line
    {
        std::istringstream iss{line}; // construct a string stream from line

        // read the tokens from current line separated by comma
        std::vector<std::string> tokens; // here we store the tokens
        std::string token; // current token
        while (std::getline(iss, token, ','))
        {
            tokens.push_back(token); // add the token to the vector
        }

        // we can now process the tokens
        // first display them
        std::cout << "Tokenized line: ";
        for (const auto& elem : tokens)
            std::cout << "[" << elem << "]";
        std::cout << std::endl;

        // map the tokens into our variables, this applies to your scenario
        std::string name = tokens[0]; // first is a string, no need for further processing
        int age = std::stoi(tokens[1]); // second is an int, convert it
        int height = std::stoi(tokens[2]); // same for third
        std::cout << "Processed tokens: " << std::endl;
        std::cout << "\t Name: " << name << std::endl;
        std::cout << "\t Age: " << age << std::endl;
        std::cout << "\t Height: " << height << std::endl;
    }
}

答案 1 :(得分:0)

  

read>>name给了我整行而不只是名字。我怎么可能避免这个问题,以便我可以将整数读入年龄?

read >> name会将所有内容读入name,直到遇到空格。

如果你有一个逗号分隔的行没有空格,那么整行都会被读入name

您可以使用std::getline将整行读取为一个字符串。然后使用各种标记std::string的方法。

示例SO帖子,用于解释std::string

的标记

How do I tokenize a string in C++?
c++ tokenize std string
Splitting a C++ std::string using tokens, e.g. ";"

答案 2 :(得分:0)

你可能会使用stringstreams,但我不相信这一点,如果我是诚实的。 如果我是你,我会编写一个小函数,将整行读入一个字符串,之后,它应该搜索字符串中的分隔符。前面的一切都是第一列,第二列后面的一切。使用C ++提供的字符串操作,您可以在变量中移动这些部分(如果需要,可以将它们转换为正确的类型)。 我写了一个用于CSV解析的小型C ++库,也许看看它可以帮助你。您可以在GitHub上找到它。

编辑: 在这个要点中,您可以找到parsing function