Trabalhando com CSV em C++: bibliotecas e exemplos práticos
CSV (Comma-Separated Values) é um dos formatos mais comuns para armazenar dados tabulares. Em C++, não há suporte nativo para CSV na biblioteca padrão (até C++23), então os desenvolvedores usam bibliotecas de terceiros ou escrevem seus próprios parsers. Neste artigo, abordaremos as principais abordagens para trabalhar com CSV em C++: desde parsing manual até soluções prontas.
Por que bibliotecas para CSV são necessárias?
Arquivos CSV parecem simples, mas na prática contêm muitas armadilhas:
- Escapamento de aspas dentro de campos (por exemplo,
"Hello, world") - Valores multilinha
- Diferentes delimitadores (vírgula, ponto e vírgula, tabulação)
- Codificações diferentes (UTF-8, UTF-16, ANSI)
Bibliotecas prontas resolvem esses problemas e economizam tempo.
1. Parsing manual de CSV (sem bibliotecas de terceiros)
Para casos simples, você pode escrever seu próprio parser. Exemplo de leitura de CSV usando std::ifstream e std::getline:
#include <iostream>#include <fstream>#include <sstream>#include <vector>#include <string>
std::vector<std::vector<std::string>> parseCSV(const std::string& filename) { std::vector<std::vector<std::string>> data; std::ifstream file(filename); std::string line;
while (std::getline(file, line)) { std::vector<std::string> row; std::stringstream ss(line); std::string cell;
while (std::getline(ss, cell, ',')) { // Remove aspas extras (simplificado) if (cell.size() >= 2 && cell.front() == '"' && cell.back() == '"') { cell = cell.substr(1, cell.size() - 2); } row.push_back(cell); } data.push_back(row); } return data;}Desvantagens: não trata vírgulas escapadas dentro de aspas, campos multilinha, linhas vazias no final do arquivo.
2. Biblioteca libcsv (C)
libcsv é uma biblioteca leve em C que faz parsing de CSV corretamente de acordo com a RFC 4180. Adequada para projetos onde o desempenho é importante.
Instalação (Linux): sudo apt-get install libcsv-dev
#include <csv.h>#include <iostream>#include <vector>
void cb1(void *s, size_t len, void *data) { std::string field(static_cast<char*>(s), len); static_cast<std::vector<std::string>*>(data)->push_back(field);}
void cb2(int c, void *data) { if (c == CsvRowEnd) { // Fim da linha — exibe auto& row = *static_cast<std::vector<std::string>*>(data); for (const auto& f : row) std::cout << f << " | "; std::cout << ""; row.clear(); }}
int main() { FILE *fp = fopen("data.csv", "r"); if (!fp) return 1;
struct csv_parser p; csv_init(&p, CSV_STRICT);
std::vector<std::string> row; char buf[1024]; size_t bytes_read;
while ((bytes_read = fread(buf, 1, sizeof(buf), fp)) > 0) { csv_parse(&p, buf, bytes_read, cb1, cb2, &row); } csv_fini(&p, cb1, cb2, &row); csv_free(&p); fclose(fp); return 0;}3. Biblioteca rapidcsv (C++ header-only)
rapidcsv é uma biblioteca moderna em C++17 que funciona apenas com arquivos de cabeçalho. Suporta detecção automática de delimitador, trabalho com diferentes tipos de dados e escrita de CSV.
Instalação: copiar rapidcsv.h para o projeto.
#include "rapidcsv.h"#include <iostream>#include <vector>
int main() { // Leitura de CSV rapidcsv::Docum Também na biblioteca
Pest para PHP: guia completo com exemplos
Envio de email em Rust: bibliotecas lettre e mailparse para mensagens
Trabalho com imagens em Rust: visão geral das bibliotecas image, fast_image_resize e outras