Split one CSV line properly
An import job reads a CSV where some fields legitimately contain commas, so splitting on the comma alone corrupts the data.
- Commas separate fields, except inside a double-quoted field.
- Inside a quoted field, two double quotes in a row mean one literal quote.
- The quotes themselves are not part of the value.
- An empty line gives an empty list; an empty field between two commas gives an empty string.
parseCsvLine(line: string) → list<string>
C++ needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.
Where you start
std::vector<std::string> parseCsvLine(std::string line) {
}
Worked examples
| Call | Result |
|---|---|
parseCsvLine(std::string("a,b,c")) | std::vector<std::string>{std::string("a"), std::string("b"), std::string("c")} |
parseCsvLine(std::string("a,\"b,c\",d")) | std::vector<std::string>{std::string("a"), std::string("b,c"), std::string("d")} |
parseCsvLine(std::string("\"say \"\"hi\"\"\",x")) | std::vector<std::string>{std::string("say \"hi\""), std::string("x")} |
parseCsvLine(std::string("a,,b")) | std::vector<std::string>{std::string("a"), std::string(""), std::string("b")} |
Hint
Walk the line one character at a time carrying a single boolean: are we inside quotes right now.
Reference solution in C++
std::vector<std::string> parseCsvLine(std::string line) {
if (line.empty()) return {};
std::vector<string> fields;
string cur;
bool quoted = false;
size_t i = 0;
while (i < line.size()) {
char c = line[i];
if (quoted) {
if (c == '"') {
if (i + 1 < line.size() && line[i + 1] == '"') { cur += '"'; i += 2; continue; }
quoted = false; i++; continue;
}
cur += c; i++;
} else if (c == '"') { quoted = true; i++; }
else if (c == ',') { fields.push_back(cur); cur.clear(); i++; }
else { cur += c; i++; }
}
fields.push_back(cur);
return fields;
}