c++stringc++17istringstream

string stream never terminates in while loop


I want to write a generic function to parse CSV files. My code acts very strange as it never stops and repeats the first line forever. What am I doing wrong here?

#include <vector>
#include <string>
#include <sstream>
#include <iostream>
std::vector<std::vector<std::string>> parseCsvFile(std::string_view source,
                                                   char valueSeparator) {
    auto reult = std::vector<std::vector<std::string>>();
    for(std::string line;
        std::getline(std::istringstream(source.data()), line);
        /* emoty cond */) {
        std::istringstream stream(line);
        std::string token;

        while(std::getline(stream, token, valueSeparator)) { // never ends
            // debug
            std::cout << token << "\n" << std::endl;
            // push to vector
        }
    }

    return reult;
}

void test() {
    auto testData = std::string("a,b,c,d\r\ne,f,g,h\r\n");
    const auto data = parseCsvFile(testData, ','); // Never ends
}

Solution

  • The problem is with the for loop:

    for(std::string line;
        std::getline(std::istringstream(source.data()), line);
        /* emoty cond */)
    

    The expression std::istringstream(source.data()) creates a brand new istringstream object from scratch each iteration of the loop. You never get beyond the first line in the input string source.

    You need to create the string stream before the loop, and then use it in the loop:

    std::istringstream source_stream(source.data());
    for(std::string line;
        std::getline(source_stream, line);
        /* emoty cond */)
    

    On a different note: The term "cond" means a "condition". And the condition isn't empty, it's the third "expression" clause that's empty. The condition is the std::getline call.