11

I want to read csv file by using c++ so here is my code

 int main(){
 ifstream classFile("class.csv");
 vector<string> classData;

 while (getline(classFile, line,',')) // there is input overload classfile
        {
            classData.push_back(line);  

        }
}

here is my question : my problem is when it reads the last column of each row (since it is not separated by comma) it reads last column data and first of next row data for example if my data was like

className, classLocation, Professor c++, Library, John

then it reads like className/ classLocation/ Professor c++/ Library / John

is there anyway that I can separate my last column from first of next row? Thank you and sorry that it is confusing

programing_is_hard
  • 442
  • 1
  • 6
  • 16
  • 1
    CSV is supposed to have a end-of-line after each record. Does your csv has an end-of-line after each record? What you can do is first get the line and afterwards, divide using `,`. – wendelbsilva Nov 12 '13 at 18:01
  • 1
    http://stackoverflow.com/questions/7621727/split-a-string-into-words-by-multiple-delimiters-in-c you are going to use 2 delimiter `,` and `\n` in your case you are using only `,` so the `\n` becomes a part of the string – abasu Nov 12 '13 at 18:04
  • possible duplicate of [Splitting a line of a csv file into a std::vector?](http://stackoverflow.com/questions/11310947/splitting-a-line-of-a-csv-file-into-a-stdvector) – Jonathan Mee Mar 31 '15 at 19:37

3 Answers3

28

Read the file line by line:

std::string line;
while(std::getline(stream, line)) ...

Pass each line to a istingstream and read the fields:

std::istringstream s(line);
std::string field;
while (getline(s, field,',')) ...

Disclaimer: This is a simplified parsing of a csv-file.

  • 1
    Definitely in a loop of some kind. A while loop is a decent choice because you don't necessarily know how long the .csv file will be, and the terminating condition will just be running out of lines. – RangerRick Nov 12 '13 at 18:08
  • wow!! it works!! I have absolutely no idea how or why but it works!! XD thanks!! – programing_is_hard Nov 12 '13 at 18:13
  • and I guess it suppose to be istringstream s(line)? cuz istringstream(line) s does not work.. but thank you so much! – programing_is_hard Nov 12 '13 at 18:15
5

Sorry, can I shove in some plain C into this thread?

Reading csv is pretty clear there:

#include <stdio.h>


int main()
{
  float f1, f2;

  FILE *fp;
  fp = fopen("file.csv", "r");

  while (fscanf(fp, "%g,%g\n", &f1, &f2) == 2)
    printf("%g\n", f1+f2);
}

And quite certainly it should work where C++ works.

There, in the while, we check how many objects fscanf has found: fscanf(fp, "%g,%g\n", &f1, &f2) == 2 -- fscanf returns number of objects it finds.

I hope it might be of help to someone.

(And if anybody would like to see more info on fscanf and reading files -- leave some comments.)

xealits
  • 4,224
  • 4
  • 27
  • 36
  • Won't this break under the most trivial changes to the CSV format, for example having a space after the comma or a different (non-unix) line break? – j b Aug 24 '14 at 22:56
  • 2
    yes, it most certainly will break. And, adding to the problem of spaces in CSV file, the number of fields is fixed in the program, which is not the case with getline. (Though, usually the number of fields is fixed in CSVs.) – xealits Aug 26 '14 at 11:09
2

In case you are interested to have a void function to be called in your main section, please take a look at the following code:

void readCSV(const string &strPath2Dataset)
{   
    ifstream csvFile;
    string strPathCSVFile = strPath2Dataset + "/test.csv";
    csvFile.open(strPathCSVFile.c_str());

    if (!csvFile.is_open())
    {
        cout << "Path Wrong!!!!" << endl;
        exit(EXIT_FAILURE);
    }

    vector<long double> timeStampIMU;
    vector<long double> gyro_X;
    vector<long double> gyro_Y;
    vector<long double> gyro_Z;

    vector<long double> acc_X;
    vector<long double> acc_Y;
    vector<long double> acc_Z;

    string line;
    vector <string> vec;
    getline(csvFile, line); // skip the 1st line

    while (getline(csvFile,line))
    {
        if (line.empty()) // skip empty lines:
        {
            //cout << "empty line!" << endl;
            continue;
        }

        istringstream iss(line);
        string lineStream;
        string::size_type sz;

        vector <long double> row;

        while (getline(iss, lineStream, ','))
        {  
            row.push_back(stold(lineStream,&sz)); // convert to double
        }

        timeStampIMU.push_back(row[0]);

        gyro_X.push_back(row[1]);
        gyro_Y.push_back(row[2]);
        gyro_Z.push_back(row[3]);

        acc_X.push_back(row[4]);
        acc_Y.push_back(row[5]);
        acc_Z.push_back(row[6]);
    }

    //cout << "size ts = " << timeStampIMU.size() << endl;
    for (size_t i = 0; i < timeStampIMU.size(); i++)
    {
        cout << "ts_imu = " << setprecision(12) << timeStampIMU[i] << endl;

        cout << "gx = " << setprecision(12) << gyro_X[i] << endl;
        cout << "gy = " << setprecision(12) << gyro_Y[i] << endl;
        cout << "gz = " << setprecision(12) << gyro_Z[i] << endl;

        cout << "ax = " << setprecision(12) << acc_X[i] << endl;
        cout << "ay = " << setprecision(12) << acc_Y[i] << endl;
        cout << "az = " << setprecision(12) << acc_Z[i] << endl;
        cout << "--------------------------------" << endl;
    }
}

My .csv file is dataset provided from IMU sensor, separated by comma:

TimeStamp, Gyro_X, Gyro_Y, Gyro_Z, Acc_X, Acc_Y, Acc_Z
Farid Alijani
  • 839
  • 1
  • 7
  • 25