Trabajo con CSV en C++: desde el análisis manual hasta la biblioteca libcsv
El formato CSV (Valores Separados por Comas) sigue siendo una de las formas más populares de intercambiar datos tabulares. En C++ no hay soporte integrado para CSV, pero existen varios enfoques efectivos: análisis manual utilizando herramientas estándar y bibliotecas especializadas como libcsv. En este artículo analizaremos ambos métodos, sus ventajas y desventajas, y proporcionaremos ejemplos de código funcionales.
Qué es CSV y sus características
CSV es un formato de texto donde cada línea corresponde a un registro y los campos están separados por comas. Las principales dificultades son:
- Los campos pueden contener comas si están entre comillas (
"Hola, mundo"); - Las comillas dentro de un campo se escapan duplicándolas (
""); - El separador puede ser otro carácter (punto y coma, tabulación);
- Las líneas pueden contener caracteres de nueva línea dentro de las comillas.
Por lo tanto, simplemente dividir la línea por comas a menudo genera errores. Consideremos dos métodos fiables.
Método 1: Análisis manual con std::stringstream
Adecuado para CSV simples sin comillas anidadas ni saltos de línea. La implementación consta de dos funciones: lectura de un campo y análisis de toda la línea.
#include <iostream>#include <fstream>#include <sstream>#include <vector>#include <string>
// Dividir una línea CSV en campos considerando comillasstd::vector<std::string> parseCSVLine(const std::string& line) { std::vector<std::string> fields; std::string field; bool inQuotes = false;
for (size_t i = 0; i < line.size(); ++i) { char c = line[i]; if (c == '"' && !inQuotes) { inQuotes = true; } else if (c == '"' && inQuotes) { // Verificar comillas escapadas if (i + 1 < line.size() && line[i + 1] == '"') { field += '"'; ++i; // saltar la siguiente comilla } else { inQuotes = false; } } else if (c == ',' && !inQuotes) { fields.push_back(field); field.clear(); } else { field += c; } } fields.push_back(field); // último campo return fields;}
int main() { std::ifstream file("data.csv"); std::string line;
while (std::getline(file, line)) { auto fields = parseCSVLine(line); for (const auto& f : fields) { std::cout << "[" << f << "] "; } std::cout << std::endl; } return 0;}Ventajas: sin dependencias externas, control total sobre la lógica.
Desventajas: no maneja campos multilínea (valor que contiene ), requiere manejo manual de errores.
Método 2: Biblioteca libcsv
libcsv es una biblioteca ligera en C para analizar CSV, escrita en C pero que funciona perfectamente desde C++. Maneja correctamente todos los casos estándar: comillas, escape, campos multilínea, separadores personalizados.
Instalación
Descargue los fuentes desde SourceForge o instálelo mediante el gestor de paquetes:
# Linux (Debian/Ubuntu)sudo apt-get install libcsv-dev
# macOSbrew install libcsvEjemplo de lectura de CSV con libcsv
#include <iostream>#include <fstream>#include <vector>#include <string>#include <cstring>#include <csv.h>
// Estructura para almacenar datosstruct CSVData { std::vector<std::vector<std::string>> rows; std::vector<std::string> currentRow;};
// Ca También en la biblioteca
Trabajo con Kafka en PHP: bibliotecas, instalación y ejemplos de código
Migraciones de bases de datos en Go: revisión de herramientas y prácticas
Configuración de aplicaciones Swift: herramientas y bibliotecas para iOS/macOS
Validación de datos en Rust: biblioteca validator
Generación de códigos QR en Java: biblioteca ZXing (guía detallada)