Это решение обнаруживает эти 4 случая
. Полный класс находится в
https://github.com/pedro-vicente/csv-parser
1,field 2,field 3,
1,field 2,"field 3 quoted, with separator",
1,field 2,"field 3
with newline",
1,field 2,"field 3
with newline and separator,",
Он читает символ файла по символу и читает по 1 строке за один раз вектору (строк), поэтому подходит для очень больших файлов.
Использование
Итерация до тех пор, пока не будет возвращена пустая строка (конец файла). Строка представляет собой вектор, в котором каждая запись представляет собой столбец CSV.
read_csv_t csv;
csv.open("../test.csv");
std::vector row;
while (true)
{
row = csv.read_row();
if (row.size() == 0)
{
break;
}
}
объявление класса
class read_csv_t
{
public:
read_csv_t();
int open(const std::string &file_name);
std::vector read_row();
private:
std::ifstream m_ifs;
};
реализация
std::vector read_csv_t::read_row()
{
bool quote_mode = false;
std::vector row;
std::string column;
char c;
while (m_ifs.get(c))
{
switch (c)
{
/////////////////////////////////////////////////////////////////////////////////////////////////////
//separator ',' detected.
//in quote mode add character to column
//push column if not in quote mode
/////////////////////////////////////////////////////////////////////////////////////////////////////
case ',':
if (quote_mode == true)
{
column += c;
}
else
{
row.push_back(column);
column.clear();
}
break;
/////////////////////////////////////////////////////////////////////////////////////////////////////
//quote '"' detected.
//toggle quote mode
/////////////////////////////////////////////////////////////////////////////////////////////////////
case '"':
quote_mode = !quote_mode;
break;
/////////////////////////////////////////////////////////////////////////////////////////////////////
//line end detected
//in quote mode add character to column
//return row if not in quote mode
/////////////////////////////////////////////////////////////////////////////////////////////////////
case '\n':
case '\r':
if (quote_mode == true)
{
column += c;
}
else
{
return row;
}
break;
/////////////////////////////////////////////////////////////////////////////////////////////////////
//default, add character to column
/////////////////////////////////////////////////////////////////////////////////////////////////////
default:
column += c;
break;
}
}
//return empty vector if end of file detected
m_ifs.close();
std::vector v;
return v;
}