العمل مع CSV في C++: المكتبات، التحليل وكتابة البيانات

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

العمل مع CSV في C++: المكتبات والأمثلة العملية



CSV (Comma-Separated Values) — أحد أكثر التنسيقات شيوعًا لتخزين البيانات الجدولية. لا يوجد دعم مدمج لـ CSV في المكتبة القياسية لـ C++ (حتى C++23)، لذلك يستخدم المطورون مكتبات خارجية أو يكتبون محللات خاصة بهم. في هذه المقالة، سنستعرض الأساليب الأساسية للعمل مع CSV في C++: من التحليل اليدوي إلى الحلول الجاهزة.



لماذا نحتاج إلى مكتبات لـ CSV؟

قد تبدو ملفات CSV بسيطة، لكنها تحتوي عمليًا على العديد من المزالق:

  • إفلات علامات الاقتباس داخل الحقول (مثل "Hello, world")
  • القيم متعددة الأسطر
  • فواصل مختلفة (فاصلة، فاصلة منقوطة، علامة تبويب)
  • ترميزات مختلفة (UTF-8, UTF-16, ANSI)

المكتبات الجاهزة تحل هذه المشاكل وتوفر الوقت.



1. التحليل اليدوي لـ CSV (بدون مكتبات خارجية)

للحالات البسيطة، يمكن كتابة محلل بنفسك. مثال على قراءة CSV باستخدام std::ifstream و 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, ',')) { // إزالة علامات الاقتباس الزائدة (بشكل مبسط) 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;}


العيوب: لا يعالج الفواصل المُفلاتة داخل علامات الاقتباس، الحقول متعددة الأسطر، الأسطر الفارغة في نهاية الملف.



2. مكتبة libcsv (C)

libcsv — مكتبة خفيفة الوزن بلغة C، تقوم بتحليل CSV بشكل صحيح وفقًا لـ RFC 4180. مناسبة للمشاريع التي تكون فيها الأداء مهمًا.

التثبيت (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) { // نهاية السطر — طباعة 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. مكتبة rapidcsv (C++ header-only)

rapidcsv — مكتبة حديثة بلغة C++17، تعمل فقط مع ملفات الرأس. تدعم التحديد التلقائي للفاصل، العمل مع أنواع بيانات مختلفة، وكتابة CSV.

التثبيت: نسخ rapidcsv.h إلى المشروع.



#include "rapidcsv.h"#include <iostream>#include <vector>

int main() { // قراءة CSV rapidcsv::Docum

توصيات