Как я могу читать и редактировать данные файла CSV на C ++?

Довольно понятный, я попробовал google и получил много страшного expertsexchange, я искал здесь также безрезультатно. Лучше всего было бы использовать онлайн-учебник или пример. Спасибо, парни.

Если то, что вы действительно делаете, это манипулирование самим файлом CSV, ответ Нельсона имеет смысл. Однако мое подозрение в том, что CSV – это просто артефакт проблемы, которую вы решаете. В C ++ это, вероятно, означает, что у вас есть что-то подобное в качестве модели данных:

struct Customer { int id; std::string first_name; std::string last_name; struct { std::string street; std::string unit; } address; char state[2]; int zip; }; 

Таким образом, когда вы работаете с набором данных, имеет смысл иметь std::vector или std::set .

Имея это в виду, подумайте о своей обработке CSV как о двух операциях:

 // if you wanted to go nuts, you could use a forward iterator concept for both of these class CSVReader { public: CSVReader(const std::string &inputFile); bool hasNextLine(); void readNextLine(std::vector &fields); private: /* secrets */ }; class CSVWriter { public: CSVWriter(const std::string &outputFile); void writeNextLine(const std::vector &fields); private: /* more secrets */ }; void readCustomers(CSVReader &reader, std::vector &customers); void writeCustomers(CSVWriter &writer, const std::vector &customers); 

Чтение и запись одной строки за раз, а не сохранение полного представления в файле самого файла. Есть несколько очевидных преимуществ:

  1. Ваши данные представлены в форме, которая имеет смысл для вашей проблемы (клиентов), а не для текущего решения (файлы CSV).
  2. Вы можете тривиально добавлять адаптеры для других форматов данных, таких как объемный импорт / экспорт SQL, файлы электронной таблицы Excel / OO или даже рендеринг HTML

    .

  3. Вероятно, ваш объем памяти будет меньше (зависит от относительного sizeof(Customer) и количества байтов в одной строке).
  4. CSVReader и CSVWriter могут быть повторно использованы в качестве основы для модели с памятью (например, Nelson’s) без потери производительности или функциональности. Обратное неверно.

Больше информации было бы полезно.

Но простейшая форма:

 #include  #include  #include  #include  int main() { std::ifstream data("plop.csv"); std::string line; while(std::getline(data,line)) { std::stringstream lineStream(line); std::string cell; while(std::getline(lineStream,cell,',')) { // You have a cell!!!! } } } в #include  #include  #include  #include  int main() { std::ifstream data("plop.csv"); std::string line; while(std::getline(data,line)) { std::stringstream lineStream(line); std::string cell; while(std::getline(lineStream,cell,',')) { // You have a cell!!!! } } } в #include  #include  #include  #include  int main() { std::ifstream data("plop.csv"); std::string line; while(std::getline(data,line)) { std::stringstream lineStream(line); std::string cell; while(std::getline(lineStream,cell,',')) { // You have a cell!!!! } } } 

Также см. Этот вопрос: синтаксический анализатор CSV в C ++

Вы можете попробовать использовать библиотеку Boost Tokenizer, в частности Separator с экранированным списком

В свое время я работал с большим количеством файлов CSV. Я хотел бы добавить совет:

1 – В зависимости от источника (Excel и т. Д.) В поле могут быть встроены запятые или вкладки. Обычно правило заключается в том, что они будут «защищены», потому что поле будет ограничено двойными кавычками, как в «Boston, MA 02346».

2 – Некоторые источники не будут дублировать все текстовые поля. Другие источники. Другие будут разграничивать все поля, даже цифры.

3 – Поля, содержащие двойные кавычки, обычно получают двойные двойные кавычки (и само поле ограничивается двойными кавычками, как в «Джордже» «Babe» «Ruth».

4 – Некоторые источники будут включать CR / LF (один из них – Excel!). Иногда это будет просто CR. Поле, как правило, будет разделено на две кавычки, но эту ситуацию очень сложно обработать.

Это хорошее упражнение для себя, чтобы работать на 🙂

Вы должны разбить свою библиотеку на три части

  • Загрузка файла CSV
  • Представление файла в памяти, чтобы вы могли его изменить и прочитать
  • Сохранение CSV-файла на диск

Итак, вы смотрите на создание classа CSVDocument, который содержит:

  • Загрузить (const char * файл);
  • Сохранить (const char * файл);
  • GetBody

Чтобы вы могли использовать свою библиотеку следующим образом:

 CSVDocument doc; doc.Load("file.csv"); CSVDocumentBody* body = doc.GetBody(); CSVDocumentRow* header = body->GetRow(0); for (int i = 0; i < header->GetFieldCount(); i++) { CSVDocumentField* col = header->GetField(i); cout << col->GetText() << "\t"; } for (int i = 1; i < body->GetRowCount(); i++) // i = 1 so we skip the header { CSVDocumentRow* row = body->GetRow(i); for (int p = 0; p < row->GetFieldCount(); p++) { cout << row->GetField(p)->GetText() << "\t"; } cout << "\n"; } body->GetRecord(10)->SetText("hello world"); CSVDocumentRow* lastRow = body->AddRow(); lastRow->AddField()->SetText("Hey there"); lastRow->AddField()->SetText("Hey there column 2"); doc->Save("file.csv"); 

Это дает нам следующие интерфейсы:

 class CSVDocument { public: void Load(const char* file); void Save(const char* file); CSVDocumentBody* GetBody(); }; class CSVDocumentBody { public: int GetRowCount(); CSVDocumentRow* GetRow(int index); CSVDocumentRow* AddRow(); }; class CSVDocumentRow { public: int GetFieldCount(); CSVDocumentField* GetField(int index); CSVDocumentField* AddField(int index); }; class CSVDocumentField { public: const char* GetText(); void GetText(const char* text); }; 

Теперь вам просто нужно заполнить пробелы здесь 🙂

Поверьте мне, когда я это скажу – вкладывая свое время в изучение того, как создавать библиотеки, особенно те, которые имеют дело с загрузкой, манипулированием и сохранением данных, не только устранит вашу зависимость от существования таких библиотек, но и сделает вас все- вокруг лучшего программиста.

🙂

РЕДАКТИРОВАТЬ

Я не знаю, сколько вы уже знаете о манипуляциях с строками и синтаксическом анализе; поэтому, если вы застряли, я буду рад помочь.

Вот какой код вы можете использовать. Данные из csv хранятся внутри массива строк. Каждая строка представляет собой массив строк. Надеюсь это поможет.

 #include  #include  #include  #include  #include  typedef std::string String; typedef std::vector CSVRow; typedef CSVRow::const_iterator CSVRowCI; typedef std::vector CSVDatabase; typedef CSVDatabase::const_iterator CSVDatabaseCI; void readCSV(std::istream &input, CSVDatabase &db); void display(const CSVRow&); void display(const CSVDatabase&); int main(){ std::fstream file("file.csv", std::ios::in); if(!file.is_open()){ std::cout << "File not found!\n"; return 1; } CSVDatabase db; readCSV(file, db); display(db); } void readCSV(std::istream &input, CSVDatabase &db){ String csvLine; // read every line from the stream while( std::getline(input, csvLine) ){ std::istringstream csvStream(csvLine); CSVRow csvRow; String csvCol; // read every element from the line that is seperated by commas // and put it into the vector or strings while( std::getline(csvStream, csvCol, ',') ) csvRow.push_back(csvCol); db.push_back(csvRow); } } void display(const CSVRow& row){ if(!row.size()) return; CSVRowCI i=row.begin(); std::cout<<*(i++); for(;i != row.end();++i) std::cout<<','<<*i; } void display(const CSVDatabase& db){ if(!db.size()) return; CSVDatabaseCI i=db.begin(); for(; i != db.end(); ++i){ display(*i); std::cout< 

Использование boost tokenizer для анализа записей , см. Здесь для получения более подробной информации .

 ifstream in(data.c_str()); if (!in.is_open()) return 1; typedef tokenizer< escaped_list_separator > Tokenizer; vector< string > vec; string line; while (getline(in,line)) { Tokenizer tok(line); vec.assign(tok.begin(),tok.end()); /// do something with the record if (vec.size() < 3) continue; copy(vec.begin(), vec.end(), ostream_iterator(cout, "|")); cout << "\n----------------------" << endl; } 

Посмотрите на « Практику программирования » (TPOP) Kernighan & Pike. Он включает пример parsingа CSV-файлов в C и C ++. Но стоило бы прочитать книгу, даже если вы не используете код.

(Предыдущий URL: http://cm.bell-labs.com/cm/cs/tpop/ )

Я нашел этот интересный подход:

Утилита CSV в C

Цитата: CSVtoC – это программа, которая берет CSV или файл значений разделенных запятыми в качестве входных данных и выгружает их как структуру C.

Естественно, вы не можете вносить изменения в CSV-файл, но если вам нужен только доступ к данным в режиме «только для чтения», он может работать.

  • Как выводить результаты запросов MySQL в формате CSV?
  • Ruby on Rails - импорт данных из файла CSV
  • преобразование CSV / XLS в JSON?
  • Есть ли простой способ конвертировать .xls-файл в CSV-файл? (Excel)
  • Добавить пробел после n-й запятой в Excel, Notepad ++ или emEditor?
  • Могу ли я создать колоду Anki из файла .CSV?
  • Как сделать блокнот для сохранения текста в UTF-8 без спецификации?
  • Экспорт базы данных SQLite в файл csv в android
  • Прокрутка файлов в папке в matlab
  • Как я могу импортировать данные из CSV в MySQL?
  • Как помочь Excel разобрать мой CSV автоматически
  • Давайте будем гением компьютера.