vincentlaucsb / csv-parser

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

New line at EOF returned as row when using std::ifstream and CSVFormat::no_header() #149

Open Plukers opened 3 years ago

Plukers commented 3 years ago

Hey thanks for the great library!

I observed an issue where if a file ends with a new line, the empty last line is returned as a row of size 1. This was observed when using std::ifstream and CSVFormat::no_header()

This file with the following test case fails: TooManyLines.zip

TEST_CASE("ifstream: Wrong number of rows", "[ifstream_read_wrong_number_of_rows_csv]") {
    CSVFormat format;
    format.no_header();

    std::ifstream source("./tests/data/real_data/TooManyLines.csv");
    CSVReader reader(source, format);

    REQUIRE(reader.empty());

    // Expected results
    size_t row_no = 0;
    for (auto& row : reader) {
        if (row_no == 1) {
            REQUIRE(row.size() == 0);
        }
        row_no++;
    }

    REQUIRE(row_no == 1);
}

On the other hand, this test case using std::stringstream works:

TEST_CASE("stringstream: Wrong number of rows", "[stringstream_read_wrong_number_of_rows_csv]") {
    CSVFormat format;
    format.no_header();

    std::stringstream csv_string("A,B,C\r\n");
    CSVReader reader(csv_string, format);

    REQUIRE(reader.empty());

    // Expected results
    size_t row_no = 0;
    for (auto& row : reader) {
        if (row_no == 1) {
            REQUIRE(row.size() == 0);
        }
        row_no++;
    }

    REQUIRE(row_no == 1);
}
netromdk commented 2 years ago

Could someone take a look at this issue? Thank you.