Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading two columns in CSV file in c++

Tags:

c++

csv

I have a CSV file in the form of two columns: name, age

To read and store the info, I did this

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

However, when I did

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

read>>name gave me the whole line instead of just the name. How could I possibly avoid this problem so that I can read the integer into age?

Thank you!

like image 349
Dinosaur Avatar asked May 12 '15 04:05

Dinosaur


1 Answers

You can first read the whole line with std:getline, then parse it via a std::istringstream (must #include <sstream>), like

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
}

Below is a fully working general example that tokenizes a CSV file 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;
    }
}
like image 199
vsoftco Avatar answered Oct 07 '22 01:10

vsoftco