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
}
The problem is with the
forloop:The expression
std::istringstream(source.data())creates a brand newistringstreamobject from scratch each iteration of the loop. You never get beyond the first line in the input stringsource.You need to create the string stream before the loop, and then use it in the loop:
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::getlinecall.