Мне нужно загрузить и использовать данные файла CSV в C ++. На данный момент это может быть просто парсер, разделенный запятыми (т.е. не беспокойтесь о экранировании новых строк и запятых). Основная потребность - построчный анализатор, который будет возвращать вектор для следующей строки каждый раз, когда вызывается метод.
Я нашел эту статью, которая выглядит многообещающей: http://www.boost.org/doc/libs/1_35_0/libs/spirit/example/fundamental/list_parser.cpp
Я никогда не использовал Boost's Spirit, но готов попробовать. Но только если нет более простого решения, я пропускаю.
boost::spirit
разбор. Это больше для разбора грамматики, спасибо разбору простого формата файла. Кто-то в моей команде пытался использовать его для разбора XML, и отладка была сложной задачей. Держитесь подальше от,boost::spirit
если это возможно.spirit
довольно сложно использовать для библиотеки комбинатора синтаксического анализатора. Имея некоторый (очень приятный) опыт работы с(atto)parsec
библиотеками Haskells, я ожидал, что он (дух) будет работать так же хорошо, но отказался от него после борьбы с ошибками 600-строчного компилятора.Ответы:
Если вас не волнует экранирование запятой и новой строки,
И вы не можете вставлять запятую и новую строку в кавычки (Если вы не можете выйти затем ...),
тогда это всего лишь три строки кода (ОК 14 -> Но это только 15, чтобы прочитать весь файл).
Я бы просто создал класс, представляющий строку.
Затем поток в этот объект:
Но с небольшой работой мы могли бы технически создать итератор:
источник
istream::operator>>
(например, Eigen), добавьтеinline
перед оператором объявление, чтобы исправить это.Решение с использованием Boost Tokenizer:
источник
Моя версия не использует ничего, кроме стандартной библиотеки C ++ 11. Хорошо справляется с цитатой Excel CSV:
Код написан как конечный автомат и использует один символ за раз. Я думаю, что легче рассуждать.
источник
const char *vinit[] = {""}; vector<string> fields(vinit, end(vinit));
++ Строка Инструментарий Библиотека C (StrTk) имеет символический класс сетки , что позволяет загружать данные как из текстовых файлов, строк или символьных буферов и разбор / обрабатывать их в моде ряда столбцов.
Вы можете указать разделители строк и столбцов или просто использовать значения по умолчанию.
Больше примеров можно найти здесь
источник
options.trim_dquotes = true
), он не поддерживает удаление двойных кавычек (например, поле в"She said ""oh no"", and left."
виде c-строки"She said \"oh no\", and left."
). Тебе придется сделать это самостоятельно.strtk
вам также придется вручную обрабатывать поля в двойных кавычках, содержащие символы новой строки.Вы можете использовать Boost Tokenizer с escaped_list_separator.
При этом используются только заголовочные файлы Boost tokenizer, никаких ссылок на дополнительные библиотеки не требуется.
Вот пример (см Анализировать CSV файл с форсировкой Tokenizer В C ++ для деталей или
Boost::tokenizer
):источник
Не лишним будет использовать Дух для разбора CSV. Spirit хорошо подходит для задач микропарсинга. Например, с Духом 2.1 это так же просто, как:
Вектор v заполняется значениями. В новых документах Spirit 2.1, которые только что были выпущены с Boost 1.41, есть серия руководств по этому вопросу.
Учебник прогрессирует от простого к сложному. Парсеры CSV представлены где-то посередине и затрагивают различные приемы использования Spirit. Сгенерированный код такой же жесткий, как и рукописный код. Проверьте созданный ассемблер!
источник
Если вы DO заботиться о разборе CSV правильно, это будет сделать ... относительно медленно , так как он работает один символ за один раз.
источник
При использовании Boost Tokenizer escaped_list_separator для CSV-файлов следует учитывать следующее:
Формат CSV, указанный в вики, утверждает, что поля данных могут содержать разделители в кавычках (поддерживается):
Формат CSV, указанный в вики, гласит, что одинарные кавычки должны обрабатываться двойными кавычками (escaped_list_separator удалит все символы кавычек):
Формат CSV не указывает, что любые символы обратной косой черты должны быть удалены (escaped_list_separator удалит все escape-символы).
Возможный обходной путь для исправления поведения по умолчанию для надстройки escaped_list_separator:
Этот обходной путь имеет побочный эффект: пустые поля данных, представленные в двойных кавычках, будут преобразованы в токен в одинарных кавычках. При переборе токенов необходимо проверить, является ли токен одинарной кавычкой, и обращаться с ним как с пустой строкой.
Не красиво, но это работает, пока в кавычках нет новых строк.
источник
Возможно, вы захотите взглянуть на мой проект FOSS CSVfix ( обновленная ссылка ), который представляет собой редактор потоков CSV, написанный на C ++. Анализатор CSV не является призом, но выполняет свою работу, и весь пакет может делать то, что вам нужно, без написания кода.
Смотрите alib / src / a_csv.cpp для парсера CSV и csvlib / src / csved_ioman.cpp (
IOManager::ReadCSV
) для примера использования.источник
Поскольку все вопросы о CSV, кажется, перенаправляются сюда, я решил опубликовать свой ответ здесь. Этот ответ не имеет прямого отношения к вопросу автора. Я хотел иметь возможность читать в потоке, который известен в формате CSV, а также типы каждого поля уже были известны. Конечно, метод ниже может использоваться для обработки каждого поля как строкового типа.
В качестве примера того, как я хотел иметь возможность использовать входной поток CSV, рассмотрим следующий вход (взятый со страницы Википедии на CSV ):
Затем я хотел иметь возможность читать данные следующим образом:
Это было решение, которое я закончил.
Со следующими помощниками, которые могут быть упрощены новыми шаблонами интегральных черт в C ++ 11:
Попробуйте онлайн!
источник
Я написал только для заголовка, C ++ 11 CSV-парсер . Он хорошо протестирован, быстр, поддерживает всю спецификацию CSV (поля в кавычках, разделитель / терминатор в кавычках, экранирование кавычек и т. Д.) И настраивается для учета CSV, которые не соответствуют спецификации.
Конфигурация осуществляется через свободный интерфейс:
Парсинг - это просто диапазон, основанный на цикле:
источник
Другая библиотека ввода / вывода CSV может быть найдена здесь:
http://code.google.com/p/fast-cpp-csv-parser/
источник
Другое решение, похожее на ответ Локи Астари , в C ++ 11. Строки здесь
std::tuple
s данного типа. Код сканирует одну строку, затем сканирует до каждого разделителя, а затем преобразует и выгружает значение непосредственно в кортеж (с небольшим количеством кода шаблона).Advanges:
std::tuple<t1, ...>
viaoperator>>
.Чего не хватает:
Основной код:
Я поместил крошечный рабочий пример на GitHub ; Я использовал его для разбора некоторых числовых данных, и он выполнил свою задачу.
источник
Вот еще одна реализация парсера Unicode CSV (работает с wchar_t). Я написал часть этого, в то время как Джонатан Леффлер написал остальное.
Примечание. Этот анализатор предназначен для максимально точного воспроизведения поведения Excel, особенно при импорте поврежденных или искаженных файлов CSV.
Это оригинальный вопрос - анализ файла CSV с многострочными полями и двойными кавычками
Это код как SSCCE (короткий, автономный, правильный пример).
источник
Мне нужна была простая в использовании библиотека C ++ для разбора файлов CSV, но я не смог найти ни одной доступной, поэтому в итоге я создал ее. Rapidcsv - это библиотека C ++ 11 только для заголовков, которая предоставляет прямой доступ к анализируемым столбцам (или строкам) в качестве векторов с выбранным типом данных. Например:
источник
Извините, но все это похоже на сложный синтаксис, скрывающий несколько строк кода.
Почему бы не это:
источник
",\n"
в строке?Вот код для чтения матрицы, обратите внимание, у вас также есть функция csvwrite в Matlab
источник
Вы можете открыть и прочитать файл .csv, используя функции fopen, fscanf, но важно проанализировать данные. Самый простой способ анализа данных - delimiter. В случае .csv delimiter равен ','.
Предположим, ваш файл data1.csv выглядит следующим образом:
Вы можете токенизировать данные и хранить их в массиве символов, а затем использовать функцию atoi () и т.д. для соответствующих преобразований.
[^,], ^ -it инвертирует логику, означает совпадение с любой строкой, которая не содержит запятую, затем последняя, говорит, что совпадает с запятой, оканчивающейся предыдущей строкой.
источник
Первое, что вам нужно сделать, это убедиться, что файл существует. Для этого вам просто нужно попытаться открыть поток файлов по пути. После того, как вы открыли файловый поток, используйте stream.fail (), чтобы увидеть, работает ли он должным образом или нет.
Вы также должны убедиться, что предоставленный файл является правильным типом файла. Для этого вам нужно просмотреть предоставленный путь к файлу, пока не найдете расширение файла. Когда у вас есть расширение файла, убедитесь, что это файл .csv.
Эта функция вернет расширение файла, которое будет использовано позже в сообщении об ошибке.
Эта функция на самом деле вызовет проверки ошибок, созданные выше, а затем проанализирует файл.
источник
Вы должны гордиться, когда используете что-то такое прекрасное, как
boost::spirit
Здесь моя попытка парсера (почти) соответствовать спецификациям CSV по этой ссылке Спецификации CSV (мне не нужны разрывы строк в полях. Также пропускаются пробелы вокруг запятых).
После преодоления шокирующего опыта ожидания 10 секунд для компиляции этого кода :), вы можете расслабиться и наслаждаться.
Обобщение:
Тест (пример украден из Википедии ):
источник
Это решение обнаруживает эти 4 случая
полный класс в
https://github.com/pedro-vicente/csv-parser
Он читает файл символ за символом и читает 1 строку за раз в вектор (из строк), поэтому подходит для очень больших файлов.
Использование
Итерируйте, пока не будет возвращена пустая строка (конец файла). Строка - это вектор, где каждая запись является столбцом CSV.
объявление класса
реализация
источник
Вы также можете взглянуть на возможности
Qt
библиотеки.Он имеет поддержку регулярных выражений, а класс QString имеет хорошие методы, например,
split()
возвращающий QStringList, список строк, полученных путем разбиения исходной строки с помощью предоставленного разделителя. Должно хватить для csv файла ..Чтобы получить столбец с заданным именем заголовка, я использую следующее: наследование c ++ проблема Qt qstring
источник
Если вы не хотите иметь дело с включением Boost в ваш проект (он достаточно велик, если все, что вы собираетесь использовать для этого, это разбор CSV ...)
Мне повезло с разбором CSV здесь:
http://www.zedwood.com/article/112/cpp-csv-parser
Он обрабатывает поля в кавычках, но не обрабатывает встроенные символы \ n (что, вероятно, подходит для большинства случаев).
источник
Это старая ветка, но она все еще находится в верхней части результатов поиска, поэтому я добавляю свое решение, используя std :: stringstream и простой метод замены строк, который нашел здесь Yves Baumes.
Следующий пример будет читать файл построчно, игнорировать строки комментариев, начинающиеся с //, и анализировать остальные строки в комбинации строк, целых и двойных чисел. Stringstream выполняет синтаксический анализ, но ожидает, что поля будут разделены пробелами, поэтому я использую stringreplace, чтобы сначала превратить запятые в пробелы. Он хорошо обрабатывает вкладки, но не работает со строками в кавычках.
Плохой или отсутствующий ввод просто игнорируется, что может или не может быть хорошим, в зависимости от ваших обстоятельств.
источник
Для чего это стоит, вот моя реализация. Он имеет дело с вводом wstring, но может быть легко настроен на строку. Он не обрабатывает символ новой строки в полях (как и мое приложение, но добавление его поддержки не слишком сложно) и не соответствует концу строки "\ r \ n" согласно RFC (при условии, что вы используете std :: getline), но он правильно обрабатывает пробелы и двойные кавычки (надеюсь).
источник
Вот готовая к использованию функция, если все, что вам нужно, это загрузить файл данных с двойным числом (без целых чисел, без текста).
источник
Другой быстрый и простой способ заключается в использовании
Boost.Fusion I/O
:Выходы:
источник
Я написал хороший способ парсинга CSV-файлов и подумал, что должен добавить его как ответ:
источник
Можно использовать
std::regex
.В зависимости от размера вашего файла и доступной вам памяти, вы можете прочитать его либо построчно, либо целиком в формате
std::string
.Чтобы прочитать файл можно использовать:
тогда вы можете сопоставить с этим, который на самом деле настраивается в соответствии с вашими потребностями.
источник
Поскольку я не привык повышать прямо сейчас, я предложу более простое решение. Предположим, что ваш CSV-файл содержит 100 строк с 10 числами в каждой строке, разделенными символом ','. Вы можете загрузить эти данные в виде массива с помощью следующего кода:
источник