Reading two columns in a CSV file in C ++

I have a CSV file as two columns: name, age

To read and save the information, 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 >> record[0].age;


read -> name gave me a whole string instead of a name. How could I avoid this problem so that I can read the integer age?



source to share

3 answers

You can read the whole line from first std:getline

, then parse it with std::istringstream

(required #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 complete working example that symbolizes the 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;





gave me a whole string instead of a name. How could I avoid this problem so that I can read the integer age?

read >> name

will read everything in name

until empty space is encountered.

If you have a comma-delimited string with no spaces, it makes sense that the entire string is read into name


You can use std::getline

to read the entire line down to one line. Then use various methods of tokenizing a std::string


An example of SO posts that address tokenization std::string


How to tokenize a string in C ++? C ++ tokenize std string
Splitting a C ++ std :: string using tokens, e.g. ""



Perhaps you could use stringstream for this, but I wouldn't trust it to be honest. If I were you, I would write a little function that reads the entire string into a string, and after that it should look for the delimiter character in the string. This is preceded by the first column and everything behind the second. With the string operations provided by C ++, you can move these parts around in your variables (you can convert them to the correct type if you need to). I wrote a small C ++ library for CSV parsing, maybe this will help you. You can find it on GitHub .

EDIT: In this Gist you can find the function



All Articles