Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ashaduri/csv-parser
Compile-time and runtime CSV parser written in C++17
https://github.com/ashaduri/csv-parser
cplusplus cplusplus-17 cpp cpp-library cpp17 csv parser
Last synced: 3 months ago
JSON representation
Compile-time and runtime CSV parser written in C++17
- Host: GitHub
- URL: https://github.com/ashaduri/csv-parser
- Owner: ashaduri
- License: zlib
- Created: 2021-02-04T12:50:12.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-05-23T18:22:05.000Z (9 months ago)
- Last Synced: 2024-10-11T02:48:28.938Z (4 months ago)
- Topics: cplusplus, cplusplus-17, cpp, cpp-library, cpp17, csv, parser
- Language: C++
- Homepage:
- Size: 885 KB
- Stars: 29
- Watchers: 3
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Csv::Parser (csv-parser)
***Compile-time and runtime CSV parser written in C++17***![GitHub](https://img.shields.io/github/license/ashaduri/csv-parser)
![Language](https://img.shields.io/badge/language-ISO%20C++17-blue)## Features
- Header-only.
- Requires only standard C++ (C++17).
- Supports reading CSV data from `std::string_view` during compilation (using `constexpr`).
- Fully supports [RFC 4180](https://www.ietf.org/rfc/rfc4180.txt), including quoted values, escaped quotes, and newlines in field values.
- Liberal in terms of accepting not-quite-standard CSV files, but detects errors when needed.
- Supports Excel CSV variations.
- Supports reading data as different types (string, double, empty field) (runtime only).
- Extensively tested using [Catch2](https://github.com/catchorg/Catch2).## API Reference
Automatically generated [API reference](https://ashaduri.github.io/csv-parser/) describes the public API in detail.
## Usage Examples
### Runtime Parsing into 2D std::vector
#### Example:
```cpp
#include "csv_parser.h"// ...
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 Csv::CellReference object. If the cell data type
// is Csv::CellType::String, Csv::CellReference object will reference a part of the original data.
// Other Cell* types, as well as floating point and integral types can also be used here.
std::vector> cell_refs;Csv::Parser parser;
try {
// This throws Csv::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
```### Runtime Parsing of Numeric Matrix Into 1D Vector With Row-Major Order
#### Example:
```cpp
#include "csv_parser.h"// ...
using namespace std::string_view_literals;
// Data to parse
std::string_view data = "11,12,13\n21,22,23"sv;// Let matrix_data be a flat matrix of doubles in row-major order.
// Other floating point and integral types, as well as Cell* types can also be used here.
std::vector matrix_data;Csv::Parser parser;
Csv::MatrixInformation info;try {
// This throws Csv::ParseError on error.
info = parser.parseToVectorRowMajor(data, matrix_data);
}
catch(Csv::ParseError& ex) {
std::cerr << "CSV parse error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}assert(matrix_data.size() == 3 * 2);
assert(info.getColumns() == 3);
assert(info.getRows() == 2);std::cout << "Row 0, column 0: " << matrix_data[0] << std::endl; // 11
std::cout << "Row 0, column 1: " << matrix_data[1] << std::endl; // 12
std::cout << "Row 0, column 2: " << matrix_data[2] << std::endl; // 13// matrixIndex(row, column) can be used to avoid accidental mistakes
std::cout << "Row 1, column 0: " << matrix_data[info.matrixIndex(1, 0)] << std::endl; // 21
std::cout << "Row 1, column 1: " << matrix_data[info.matrixIndex(1, 1)] << std::endl; // 22
std::cout << "Row 1, column 2: " << matrix_data[info.matrixIndex(1, 2)] << std::endl; // 23return EXIT_SUCCESS;
```### Compile-Time Parsing
Currently, parsing at compile-time has some restrictions:
- Only string_views are supported for output (no doubles).
- To collapse consecutive double-quotes in strings, a compile-time-allocated buffer has to be used.One (possibly useful) consequence of compile-time parsing is that a parse error also causes a compilation error.
#### Example:
```cpp
#include "csv_parser.h"// ...
using namespace std::string_view_literals;
constexpr std::string_view data =
R"(abc, "def"
"with ""quote inside",6)";constexpr std::size_t columns = 2, rows = 2;
constexpr Csv::Parser parser;
// parse into std::array, columns>
constexpr auto matrix = parser.parseTo2DArray(data);// Verify the data at compile time.
// Note that consecutive double-quotes are not collapsed when using
// getOriginalStringView(). To collapse them, use the getCleanStringBuffer()
// approach below.
static_assert(matrix[0][0].getOriginalStringView() == "abc"sv);
static_assert(matrix[1][0].getOriginalStringView() == "def"sv);
static_assert(matrix[1][1].getOriginalStringView() == "6"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 an uncollapsed string value.
// If the buffer is too small, the code will simply not compile.
constexpr auto buffer_size = matrix[0][1].getRequiredBufferSize(); // uncollapsed size
constexpr auto buffer = matrix[0][1].getCleanStringBuffer();
static_assert(buffer.getStringView() == R"(with "quote inside)"sv);
```## Copyright
Copyright: Alexander Shaduri
License: Zlib