csv-parser 1.1.0
Csv::Parser (csv-parser)
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
Csv::Parser< BehaviorPolicy > Class Template Reference

The main CSV parser class. More...

#include <csv_parser.h>

Public Member Functions

constexpr Parser ()=default
 Constructor.
 
template<typename StoreCellFunction >
constexpr void parse (std::string_view data, StoreCellFunction storeCellFunc) const
 Parse CSV string data and store the results using a callback function.
 
template<typename Vector2D >
constexpr void parseTo2DVector (std::string_view data, Vector2D &values) const
 Parse CSV string data into a vector of columns.
 
template<std::size_t rows, std::size_t columns, typename Cell = CellStringReference>
constexpr auto parseTo2DArray (std::string_view data) const
 Parse CSV string to 2D std::array, an array of columns.
 
template<typename Vector >
constexpr MatrixInformation parseToVectorRowMajor (std::string_view data, Vector &values) const
 Parse CSV string data into a flat matrix in row-major format (A11, A12, A13, A21, ...).
 
template<typename Vector >
constexpr MatrixInformation parseToVectorRowMajor (std::string_view data, Vector &values, std::optional< std::size_t > rows_hint, std::optional< std::size_t > columns) const
 Parse CSV string data into a flat matrix in row-major format (A11, A12, A13, A21, ...).
 
template<typename Vector >
constexpr MatrixInformation parseToVectorColumnMajor (std::string_view data, Vector &values, std::size_t rows, std::optional< std::size_t > columns_hint) const
 Parse CSV string data into a flat matrix in column-major format (A11, A21, A31, A12, ...).
 
template<std::size_t rows, std::size_t columns, typename Cell = CellStringReference>
constexpr auto parseToArray (std::string_view data, MatrixOrder order) const
 Parse CSV string to 1D std::array, stored in row-major or column-major order.
 

Detailed Description

template<typename BehaviorPolicy = LocaleAwareBehaviorPolicy>
class Csv::Parser< BehaviorPolicy >

The main CSV parser class.

CSV format is defined by RFC 4180: https://www.ietf.org/rfc/rfc4180.txt

RFC 4180 CSV format summary:

Considerations:

Our parser implementation details:

Member Function Documentation

◆ parse()

template<typename BehaviorPolicy >
template<typename StoreCellFunction >
constexpr void Csv::Parser< BehaviorPolicy >::parse ( std::string_view  data,
StoreCellFunction  storeCellFunc 
) const
constexpr

Parse CSV string data and store the results using a callback function.

The calling order is to always pass the first row, then the second row, etc.

Template Parameters
StoreCellFunctionCallback function with the following signature: void func(std::size_t row, std::size_t column, std::string_view cell_data, CellTypeHint hint). Deduced automatically.
Parameters
dataFull CSV string data.
storeCellFuncCallback function to store each parsed cell data.
Exceptions
ParseErrorAn exception is thrown on parse error.

◆ parseTo2DArray()

template<typename BehaviorPolicy >
template<std::size_t rows, std::size_t columns, typename Cell >
constexpr auto Csv::Parser< BehaviorPolicy >::parseTo2DArray ( std::string_view  data) const
constexpr

Parse CSV string to 2D std::array, an array of columns.

This method conveniently wraps the parse() function to simplify compile-time parsing.

Template Parameters
rowsNumber of rows
columnsNumber of columns
CellType of cell in array, e.g. CellStringReference. Must be constexpr-compatible.
Parameters
dataFull CSV string data.
Returns
std::array<std::array<Cell, rows>, columns>
Exceptions
ParseErrorAn exception is thrown on parse error.

Example:

/**************************************************************************
Copyright (C) 2021 - 2025 Alexander Shaduri
License: 0BSD (Zero-Clause BSD)
***************************************************************************/
#include "csv_parser.h"
#include <string_view>
#include <cstdlib>
int main()
{
using namespace std::string_view_literals;
constexpr std::string_view data =
R"(abc,5
,"with ""quote inside"
NaN, -Inf
)"sv;
constexpr std::size_t columns = 2, rows = 3;
constexpr Csv::Parser parser;
// parse into std::array<std::array<CellStringReference, rows>, columns>
constexpr auto matrix = parser.parseTo2DArray<rows, columns>(data);
// Verify the data at compile time.
static_assert(matrix[0][0].getOriginalStringView() == "abc"sv);
static_assert(matrix[1][0].getOriginalStringView() == "5"sv);
static_assert(matrix[0][1].getOriginalStringView().empty());
static_assert(matrix[1][1].getCleanStringBuffer<R"(with "quote inside)"sv.size()>().getStringView()
== R"(with "quote inside)"sv);
static_assert(matrix[0][2].getOriginalStringView() == "NaN"sv);
static_assert(matrix[1][2].getOriginalStringView() == " -Inf"sv);
// To support consecutive double-quote collapsing at compile-time, allocate a compile-time
// buffer to place the clean string inside. The buffer size has to be at least that
// of a collapsed string value.
// If the buffer is too small, the code will simply not compile.
constexpr auto buffer_size = matrix[1][1].getRequiredBufferSize(); // collapsed size
constexpr auto buffer = matrix[1][1].getCleanStringBuffer<buffer_size>();
static_assert(buffer.getStringView() == R"(with "quote inside)"sv);
return EXIT_SUCCESS;
}
The main CSV parser class.
Definition csv_parser.h:70
constexpr auto parseTo2DArray(std::string_view data) const
Parse CSV string to 2D std::array, an array of columns.
Definition csv_parser.h:507
Main include file for the library.

◆ parseTo2DVector()

template<typename BehaviorPolicy >
template<typename Vector2D >
constexpr void Csv::Parser< BehaviorPolicy >::parseTo2DVector ( std::string_view  data,
Vector2D &  values 
) const
constexpr

Parse CSV string data into a vector of columns.

The innermost type may be one of Cell* classes (e.g., CellReference), or a primitive numeric type (e.g., double).

Template Parameters
Vector2DA 2D vector type, e.g. std::vector<std::vector<CellReference>>, deduced automatically.
Parameters
dataFull CSV string data.
[out]valuesAn empty 2D vector to store the data in.
Exceptions
ParseErrorAn exception is thrown on parse error.

Example:

/**************************************************************************
Copyright (C) 2021 Alexander Shaduri
License: 0BSD (Zero-Clause BSD)
***************************************************************************/
#include "csv_parser.h"
#include <string_view>
#include <vector>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <fstream>
// Example of parsing predefined data and checking it at runtime
int parsePredefinedData()
{
using namespace std::string_view_literals;
// Data to parse
std::string_view data = "abc,def\n5,6"sv;
// Let "cell_refs" be a vector of columns.
// After parsing, each element will contain a std::string_view referencing a part of the original data.
std::vector<std::vector<Csv::CellReference>> cell_refs;
Csv::Parser parser;
try {
// This throws ParseError on error.
parser.parseTo2DVector(data, cell_refs);
}
catch(Csv::ParseError& ex) {
std::cerr << "CSV parse error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
assert(cell_refs.size() == 2);
assert(cell_refs[0].size() == 2);
assert(cell_refs[1].size() == 2);
assert(cell_refs[0][0].getType() == Csv::CellType::String);
assert(cell_refs[1][0].getType() == Csv::CellType::String);
assert(cell_refs[0][1].getType() == Csv::CellType::Double);
assert(cell_refs[1][1].getType() == Csv::CellType::Double);
std::cout << "Column 0, row 0: " << cell_refs[0][0].getCleanString().value() << std::endl; // abc
std::cout << "Column 1, row 0: " << cell_refs[1][0].getCleanString().value() << std::endl; // def
std::cout << "Column 0, row 1: " << cell_refs[0][1].getDouble().value() << std::endl; // 5
std::cout << "Column 1, row 1: " << cell_refs[1][1].getDouble().value() << std::endl; // 6
return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
if (argc <= 1) {
std::cout << "File not specified, using predefined data." << std::endl;
return parsePredefinedData();
}
// Load file from parameter
std::string input_file = (argv[1] ? argv[1] : "");
// Read the file to string (inefficient method, but valid for this example)
std::ifstream ifs(input_file, std::ios::binary);
if (!ifs.is_open()) {
std::cerr << "Failed to open input file " << input_file << std::endl;
return EXIT_FAILURE;
}
std::string csv_data((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
// Let "cell_refs" be a vector of columns.
// After parsing, each element will contain std::string_view referencing a part of the original data.
// Note: CellReference must NOT outlive csv_data. If it has to, use CellValue class instead.
std::vector<std::vector<Csv::CellReference>> cell_refs;
try {
Csv::Parser parser;
// This throws ParseError on error.
parser.parseTo2DVector(csv_data, cell_refs);
}
catch(Csv::ParseError& ex) {
std::cerr << "CSV parse error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
for (std::size_t column = 0; column < cell_refs.size(); ++column) {
for (std::size_t row = 0; row < cell_refs[column].size(); ++row) {
const auto& cell = cell_refs[column][row];
std::string formatted;
switch(cell.getType()) {
case Csv::CellType::Empty:
formatted = "[empty]";
break;
case Csv::CellType::Double:
formatted = std::to_string(cell.getDouble().value());
break;
case Csv::CellType::String:
formatted = cell.getCleanString().value();
break;
}
std::cout << "(row: " << (row+1) << ", col: " << (column+1) << "): " << formatted << std::endl;
}
}
return EXIT_SUCCESS;
}
Exception thrown on CSV parse error.
Definition csv_error.h:25
constexpr void parseTo2DVector(std::string_view data, Vector2D &values) const
Parse CSV string data into a vector of columns.
Definition csv_parser.h:484

◆ parseToArray()

template<typename BehaviorPolicy >
template<std::size_t rows, std::size_t columns, typename Cell >
constexpr auto Csv::Parser< BehaviorPolicy >::parseToArray ( std::string_view  data,
MatrixOrder  order 
) const
constexpr

Parse CSV string to 1D std::array, stored in row-major or column-major order.

This method conveniently wraps parse() function to simplify compile-time parsing.

Template Parameters
rowsNumber of rows
columnsNumber of columns
CellType of cell in array, e.g. CellStringReference. Must be constexpr-compatible.
Parameters
dataFull CSV string data.
orderMatrix element order (RowMajor or ColumnMajor).
Returns
std::array<Cell, rows*columns>
Exceptions
ParseErrorAn exception is thrown on parse error.

◆ parseToVectorColumnMajor()

template<typename BehaviorPolicy >
template<typename Vector >
constexpr MatrixInformation Csv::Parser< BehaviorPolicy >::parseToVectorColumnMajor ( std::string_view  data,
Vector &  values,
std::size_t  rows,
std::optional< std::size_t >  columns_hint 
) const
constexpr

Parse CSV string data into a flat matrix in column-major format (A11, A21, A31, A12, ...).

Parameters
dataFull CSV string data.
Template Parameters
VectorA flat vector type, e.g. std::vector<double>, deduced automatically.
Parameters
[out]valuesA flat (empty) matrix. This will be resized automatically.
rowsThe number of rows, required. It is needed to calculate offsets in output container.
columns_hintstd::nullopt, or the number of columns which will help with optimizing allocations.
Returns
Matrix information
Exceptions
ParseErrorAn exception is thrown on parse error.

◆ parseToVectorRowMajor() [1/2]

template<typename BehaviorPolicy >
template<typename Vector >
constexpr MatrixInformation Csv::Parser< BehaviorPolicy >::parseToVectorRowMajor ( std::string_view  data,
Vector &  values 
) const
constexpr

Parse CSV string data into a flat matrix in row-major format (A11, A12, A13, A21, ...).

The number of rows and columns is determined automatically.

Template Parameters
VectorA flat vector type, e.g. std::vector<double>, deduced automatically.
Parameters
dataFull CSV string data.
[out]valuesA flat (empty) matrix. This will be resized automatically.
Returns
Matrix information
Exceptions
ParseErrorAn exception is thrown on parse error.

Example:

/**************************************************************************
Copyright (C) 2022 Alexander Shaduri
License: 0BSD (Zero-Clause BSD)
***************************************************************************/
#include "csv_parser.h"
#include <string_view>
#include <vector>
#include <iostream>
#include <cstdlib>
#include <fstream>
// Example of parsing using 2D vector of CellDoubleValue objects
int parseUsingCellDoubleValue(std::string_view csv_data)
{
// Let "cell_values" be a vector of columns.
// After parsing, each element will contain a double value.
std::vector<std::vector<Csv::CellDoubleValue>> cell_values;
try {
Csv::Parser parser;
// This throws ParseError on error.
parser.parseTo2DVector(csv_data, cell_values);
}
catch(Csv::ParseError& ex) {
std::cerr << "CSV parse error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
for (std::size_t column = 0; column < cell_values.size(); ++column) {
for (std::size_t row = 0; row < cell_values[column].size(); ++row) {
const auto& cell = cell_values[column][row];
std::string formatted = std::to_string(cell.getValue());
std::cout << "(row: " << (row+1) << ", col: " << (column+1) << "): " << formatted << std::endl;
}
}
return EXIT_SUCCESS;
}
// Example of parsing using 2D vector of double
int parseUsingDouble(std::string_view csv_data)
{
// Let "cell_values" be a vector of columns.
// After parsing, each element will contain a double value.
std::vector<std::vector<double>> cell_values;
try {
Csv::Parser parser;
// This throws ParseError on error.
parser.parseTo2DVector(csv_data, cell_values);
}
catch(Csv::ParseError& ex) {
std::cerr << "CSV parse error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
for (std::size_t column = 0; column < cell_values.size(); ++column) {
for (std::size_t row = 0; row < cell_values[column].size(); ++row) {
const auto& cell = cell_values[column][row];
std::string formatted = std::to_string(cell);
std::cout << "(row: " << (row+1) << ", col: " << (column+1) << "): " << formatted << std::endl;
}
}
return EXIT_SUCCESS;
}
// Example of parsing to 1D vector (row-major ordering of flattened matrix).
// Float is used as storage type.
int parseUsingVectorRowMajor(std::string_view csv_data)
{
// Let "cell_values" be a matrix in row-major format.
std::vector<float> cell_values;
try {
Csv::Parser parser;
// This throws ParseError on error.
info = parser.parseToVectorRowMajor(csv_data, cell_values);
}
catch(Csv::ParseError& ex) {
std::cerr << "CSV parse error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
for (std::size_t column = 0; column < info.getColumns(); ++column) {
for (std::size_t row = 0; row < info.getRows(); ++row) {
auto value = cell_values.at(info.matrixIndex(row, column));
std::string formatted = std::to_string(value);
std::cout << "(row: " << (row+1) << ", col: " << (column+1) << "): " << formatted << std::endl;
}
}
return EXIT_SUCCESS;
}
// Example of parsing to 1D vector (column-major ordering of flattened matrix).
// Long double is used as storage type.
int parseUsingVectorColumnMajor(std::string_view csv_data, std::size_t num_rows)
{
// Let "cell_values" be a matrix in column-major format.
std::vector<long double> cell_values;
try {
Csv::Parser parser;
// This throws ParseError on error.
info = parser.parseToVectorColumnMajor(csv_data, cell_values, num_rows, std::nullopt);
}
catch(Csv::ParseError& ex) {
std::cerr << "CSV parse error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
for (std::size_t column = 0; column < info.getColumns(); ++column) {
for (std::size_t row = 0; row < info.getRows(); ++row) {
auto value = cell_values.at(info.matrixIndex(row, column));
std::string formatted = std::to_string(value);
std::cout << "(row: " << (row+1) << ", col: " << (column+1) << "): " << formatted << std::endl;
}
}
return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
if (argc <= 1) {
std::cout << "Usage: " << argv[0] << " <input.csv> [<rows>]" << std::endl;
return EXIT_FAILURE;
}
// Load file from parameter
std::string input_file = (argv[1] ? argv[1] : "");
int num_rows = std::stoi(argv[2] ? argv[2] : "0");
// Read the file to string (inefficient method, but valid for this example)
std::ifstream ifs(input_file, std::ios::binary);
if (!ifs.is_open()) {
std::cerr << "Failed to open input file " << input_file << std::endl;
return EXIT_FAILURE;
}
std::string csv_data((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
int cell_double_value_status = parseUsingCellDoubleValue(csv_data);
int double_status = parseUsingDouble(csv_data);
int matrix_row_major_status = parseUsingVectorRowMajor(csv_data);
// The number of rows *must* be given when doing column-major parsing.
int matrix_column_major_status = EXIT_SUCCESS;
if (num_rows > 0) {
matrix_column_major_status = parseUsingVectorColumnMajor(csv_data, num_rows);
}
return cell_double_value_status || double_status || matrix_row_major_status || matrix_column_major_status;
}
Matrix information (dimensions, order).
Definition csv_matrix.h:32
constexpr std::size_t getRows() const
Get number of rows in matrix.
Definition csv_matrix.h:64
constexpr std::size_t getColumns() const
Get number of columns in matrix.
Definition csv_matrix.h:78
static constexpr std::size_t matrixIndex(std::size_t row, std::size_t column, std::size_t rows, std::size_t columns, MatrixOrder order)
Get index (offset) in flat-matrix vector.
Definition csv_matrix.h:42
constexpr MatrixInformation parseToVectorColumnMajor(std::string_view data, Vector &values, std::size_t rows, std::optional< std::size_t > columns_hint) const
Parse CSV string data into a flat matrix in column-major format (A11, A21, A31, A12,...
Definition csv_parser.h:596
constexpr MatrixInformation parseToVectorRowMajor(std::string_view data, Vector &values) const
Parse CSV string data into a flat matrix in row-major format (A11, A12, A13, A21, ....
Definition csv_parser.h:527

◆ parseToVectorRowMajor() [2/2]

template<typename BehaviorPolicy >
template<typename Vector >
constexpr MatrixInformation Csv::Parser< BehaviorPolicy >::parseToVectorRowMajor ( std::string_view  data,
Vector &  values,
std::optional< std::size_t >  rows_hint,
std::optional< std::size_t >  columns 
) const
constexpr

Parse CSV string data into a flat matrix in row-major format (A11, A12, A13, A21, ...).

Template Parameters
VectorA flat vector type, e.g. std::vector<double>, deduced automatically.
Parameters
dataFull CSV string data.
[out]valuesA flat (empty) matrix. This will be resized automatically.
rows_hintstd::nullopt, or the number of rows which will help with optimizing allocations.
columnsThe number of columns. If std::nullopt, the number of columns is determined automatically.
Returns
Matrix information
Exceptions
ParseErrorAn exception is thrown on parse error.

The documentation for this class was generated from the following file: