vincentlaucsb / csv-parser

A high-performance, fully-featured CSV parser and serializer for modern C++.
MIT License
901 stars 150 forks source link

Parsing files with no header row with CSVReader #132

Open JoshuaKast opened 3 years ago

JoshuaKast commented 3 years ago

Hi!

I am having some trouble with the no_header() option in this CSV parser, when using the CSVReader object. I am using MinGW64 on Windows 10.

Please see the code below to illustrate my problem. The code should:

  1. Create a string with CSV formatted data, and save it into a file.
  2. Print the contents of that string.
  3. Create the format object we want (with no_header)
  4. Parse the CSV file on disk
  5. Parse the CSV string

I expect steps 2, 3, and 5 to print comparable results (all three rows). However, in step 4, we have trouble parsing the CSV file from disk. The no_header() option appears to be ignored.

#include <iostream>
#include "csv.hpp"

using namespace csv;

// Method for printing the fields of the CSV with spaces in between.
void printCSVFields(CSVReader& reader)
{
    for (CSVRow& row:reader) {
        for (CSVField& field:row) {
            std::cout << field.get<>() << " ";
        }
        std::cout << std::endl;
    }
}

int main()
{
    // 1. Create a CSV string and write it to a file:
    std::string csvString = "1, 2, 3\n4, 5, 6\n7, 8, 9";
    std::string fileName = "test.csv";

    std::ofstream outFile(fileName);
    outFile << csvString;
    outFile.close();

    // 2. Print the csvString
    std::cout << "Contents of csvString:\n" << csvString << "\n";

    // 3. Create the format we want to use (no header)
    CSVFormat format;
    format.no_header();

    // 4. Try reading the CSV from the file
    CSVReader myFileReader(fileName, format);
    std::cout << "\nReading from CSV file (step 4):\n";
    printCSVFields(myFileReader);

    // 5. Try reading the CSV from the string
    CSVReader myStringReader = parse(csvString, format);
    std::cout << "\nParsing from csvString: (step 5)\n";
    printCSVFields(myStringReader);

}

Output

Contents of csvString:
1, 2, 3
4, 5, 6
7, 8, 9

Reading from CSV file (step 4):
4  5  6 
7  8  9 

Parsing from csvString (step 5):
1  2  3 
4  5  6 
7  8  9 
Plukers commented 3 years ago

I observe the same issue with a file without headers and variable line length. But besides the header line, other lines are also discarded (which has probably to do with the variable line length?)

It works as expected when using std::ifstream or std::stringstream

This issue appeared for me after upgrading to 2.1.0. I did not have problems with 2.0.1, but there I had to define a pseudo header in format for it to work

tkschmidt commented 3 years ago

I observe the same issue on Linux(ARM, x86) as well as Windows.