1

I have a question about reading the content of CSV files inside C++. Basically I have a tile containing data saved in CSV format. What I would like to do is being able to read those data and allocate everything in memory on a matrix, or separate each column into a separated vector.

The first thing I am trying to do is, getting the number of lines and print the content on the consolle.

I do this by getline(stream, line, separator):

if(myFile.is_open())
{
   while(!myFile.eof())
   {
      std::getline(myFile, line, ',');
      std::cout << n_Lines << ") " << line << std::endl;
      n_Lines = n_Lines + 1;
   }
}

Now the problem is that in this way the parsing takes the commas as separators, but takes the /n (newline) into account and appends it to each last number of a row:

198) 86
199) 47
46
200) 53
201) 58
202) 4
203) 62
204) 90
205) 98
206) 58
207) 39
208) 4
34
209) 70
210) 58
211) 33
212) 8
213) 73
214) 20
215) 61
216) 9
217) 76
6
218) 22

in this cas n_Lines should count the elements, but once every ten elements, two numbers are stuck together as a whole string.

How can I avoid this and parse my file correctly? Is there a more efficient way to do this and save my data maybe directly into a matrix?

Thanks, Gio

xmoex
  • 2,602
  • 22
  • 36
user3419277
  • 13
  • 1
  • 3
  • 2
    To start with, don't do `while (!myFile.eof())`, it will not work as you expect it to. The reason is that the `eofbit` flag will not be set until *after* you try to read beyond the end of the file, so loops like that will loop once to many. Instead do `while (getline(...))` – Some programmer dude Mar 14 '14 at 10:05
  • [Read this](http://stackoverflow.com/questions/1120140/csv-parser-in-c/1120224#1120224). – WhozCraig Mar 14 '14 at 10:34
  • Is the number of columns (here==10) in one line known before reading? – cpp-progger Mar 14 '14 at 10:59

3 Answers3

0

Besides finding a proper library which can handle CSV files much better than anything you or I can come up with on short notice, you could do something like this:

Read each line into a string. Put that string in an input string stream. Read each comma-separated string from this input stream.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

If the number of columns is known before start with reading the file, following code should work:

const int NColumns = 10; // for example
while( myFile )
{
    //  start a new line in the matrix
    for( int column = 0; column < NColumns; ++column )
    {
        if( column > 0 )
            myFile >> sep<','>; // read the separator
        int x;
        if( !( myFile >> x ) )
            break; // eof or read error
        // add 'x' to the current line in the matrix
    }
}

the utility sep<> looks like this

template< char C >
std::istream& sep( std::istream& in )
{   // reads separator 'C'
    char c;
    if( in >> c && c != C )
        in.setstate( std::ios_base::failbit );
    return in;
}
cpp-progger
  • 406
  • 3
  • 6
0

I prefer using boost. Something similar to this, should work for you.

vector<string> strSplits;
boost::split(strSplits, line, boost::is_any_of(",")  );