Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

rixcpp/csv

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@rix/csv

CSV parser and writer for Rix.

@rix/csv is a small header-only C++ package for reading, writing, transforming, and inspecting CSV data.

It can be used independently, or through the unified @rix/rix facade.

Installation

vix add @rix/csv
vix install

Basic usage

#include <rix/csv.hpp>
#include <iostream>
#include <string>

int main()
{
  const std::string input =
      "name,language\n"
      "Ada,C++\n"
      "Gaspard,Vix\n";

  const rixlib::csv::Table table = rixlib::csv::parse(input);

  std::cout << "rows: " << table.size() << '\n';

  for (const auto &row : table)
  {
    for (std::size_t i = 0; i < row.size(); ++i)
    {
      if (i > 0)
      {
        std::cout << ' ';
      }

      std::cout << row[i];
    }

    std::cout << '\n';
  }

  return 0;
}

Output:

rows: 3
name language
Ada C++
Gaspard Vix

Parse CSV

const std::string input =
    "name,language\n"
    "Ada,C++\n";

const rixlib::csv::Table table = rixlib::csv::parse(input);

A table is represented as:

using Row = std::vector<std::string>;
using Table = std::vector<Row>;

So this CSV:

name,language
Ada,C++

becomes:

{
  {"name", "language"},
  {"Ada", "C++"}
}

Write CSV

const rixlib::csv::Table table = {
    {"name", "language"},
    {"Ada", "C++"},
    {"Gaspard", "Vix"},
};

const std::string output = rixlib::csv::write(table);

Output:

name,language
Ada,C++
Gaspard,Vix

Write a single row

const rixlib::csv::Row row = {"Ada", "C++", "expert"};

const std::string line = rixlib::csv::write_row(row);

Output:

Ada,C++,expert

Parsing options

rixlib::csv::Options options{};
options.skip_empty_lines = true;
options.trim_whitespace = true;

const auto table = rixlib::csv::parse(input, options);

Available options include:

options.separator = ',';
options.quote_char = '"';
options.trim_whitespace = false;
options.skip_empty_lines = false;
options.skip_comments = false;
options.comment_char = '#';
options.max_field_size = 0;
options.max_fields_per_row = 0;

You can also transform fields while parsing:

rixlib::csv::Options options{};

options.field_transformer = [](std::string &field)
{
  for (char &ch : field)
  {
    ch = static_cast<char>(std::toupper(static_cast<unsigned char>(ch)));
  }
};

const auto table = rixlib::csv::parse(input, options);

And filter rows:

rixlib::csv::Options options{};

options.row_filter = [](const rixlib::csv::Row &row)
{
  return row.size() == 2;
};

const auto table = rixlib::csv::parse(input, options);

Writing options

rixlib::csv::WriteOptions options{};
options.separator = ';';
options.line_ending = "\r\n";
options.always_quote = true;

const std::string output = rixlib::csv::write(table, options);

Available write options include:

options.separator = ',';
options.quote_char = '"';
options.line_ending = "\n";
options.always_quote = false;
options.trim_before_write = false;

Load and save files

const rixlib::csv::Table table = rixlib::csv::load("data.csv");

rixlib::csv::save("output.csv", table);

Stream support

Parse from an input stream:

std::ifstream file("data.csv", std::ios::binary);

const rixlib::csv::Table table = rixlib::csv::parse(file);

Write to an output stream:

std::ofstream file("output.csv", std::ios::binary);

rixlib::csv::write_to(file, table);

Dict-style reading

The first row can be treated as a header.

const auto table = rixlib::csv::parse(
    "name,language\n"
    "Ada,C++\n"
    "Gaspard,Vix\n");

rixlib::csv::DictReader reader{table};

for (const rixlib::csv::RowView row : reader)
{
  std::cout << row["name"] << " uses " << row["language"] << '\n';
}

Output:

Ada uses C++
Gaspard uses Vix

Select columns

const auto selected = rixlib::csv::select_columns(table, {"name"});

Read a column

const std::vector<std::string> names = rixlib::csv::column(table, "name");

Filter rows

const auto filtered = rixlib::csv::filter_rows(
    table,
    [](const rixlib::csv::Row &row)
    {
      return row.size() >= 2 && row[1] == "C++";
    });

Transform fields

const auto transformed = rixlib::csv::transform_fields(
    table,
    [](std::string &field)
    {
      field = "[" + field + "]";
    });

Describe a table

std::cout << rixlib::csv::describe(table);

Example output:

csv::Table: 3 row(s), 2 column(s)
  [header]  "name" | "language"
  [1]       "Ada" | "C++"
  [2]       "Gaspard" | "Vix"

Dialect detection

const auto dialect = rixlib::csv::sniff(sample);

rixlib::csv::Options options{};
options.separator = dialect.separator;

const auto table = rixlib::csv::parse(full_text, options);

Streaming parser

Use StreamingParser when you want to process rows without storing the full table in memory.

std::size_t count = 0;

rixlib::csv::StreamingParser parser{
    [&](const rixlib::csv::Row &row)
    {
      ++count;
    }};

parser.parse(input);

std::cout << "rows: " << count << '\n';

Version

std::cout << rixlib::csv::version() << '\n';

Unified Rix facade

When used through @rix/rix, the package is mounted under rix.csv.

#include <rix.hpp>

int main()
{
  const auto table = rix.csv.parse("name,language\nAda,C++\n");

  rix.debug.log("loaded {} rows", table.size());

  return 0;
}

Design

@rix/csv is header-only and keeps the data model simple.

rixlib::csv::Row
rixlib::csv::Table

The package exposes free functions such as:

rixlib::csv::parse(...)
rixlib::csv::write(...)
rixlib::csv::write_row(...)
rixlib::csv::load(...)
rixlib::csv::save(...)

The unified facade package @rix/rix can mount these functions as:

rix.csv.parse(...)
rix.csv.write(...)

Build

vix build

Run example

vix run

Tests

vix tests

License

MIT

About

Small CSV reader and writer for Vix C++ projects.

Resources

License

Stars

Watchers

Forks

Contributors

Morty Proxy This is a proxified and sanitized view of the page, visit original site.