Обработка xlsx файлов на C++
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Добрый день! Господа буду признателен вам за пассивную помощь.
В чём суть вопроса: изучаю я С++, читаю книги, смотрю видео уроки. Накопилось достаточно теоретических знаний (как мне кажется), но с практикой всё очень плохо.
Суть моего вопроса в следующем: у меня есть задание которое я хочу выполнить сам с минимальной помощью со стороны, но не знаю с какой стороны к нему подойти
Задача заключается в следующем: нужно написать консольное windows приложение которое будет получать на вход два параметра пути к входному(.xlsx) и выходному файлу(выдавать ошибку если значения не верны) и обрабатывать файл.
Как я думаю реализовывать:
0. подключаю <fstream>-для работы с файлами; <ifstream>-для входного файла <оfstream> для выходного;
1. Две строки для параметров входного файла и выходного файлов; (обработка ошибок для входного файла)
2. два объекта по одному для каждого класса ifstream /объект/ (/путь в переменной/) оfstream /объект/ (/путь в переменной/)
...
Ошибка №1: кроме
fstream
необходимо включать заголовкиiostream
иstring
.Ошибка №2: отсутствует тип возвращаемого значения функции
main
. Должно бытьint main() { ... }
.Ошибка №3:
cout "Входной файл:";
— отсутствует оператор вывода в поток. Должно быть так:cout << "Входной файл:";
.Ошибка №4: не хватает точки с запятой после
getline (cin, dirIN)
.Далее, фрагмент
компилятор будет считать некорректным определением функции. (С
ofstream OUTdir
всё аналогично.)Должно быть:
Выражение
ifstream INdir (dirIN);
— это определение переменной типа входного файлового потока с инициализацией (т.е. при исполнении этого выражения будет попытка открыть файл с именем, указанным вdirIN
). Затем вif
проверяем был ли корректно открыт поток. Здесь используется неявное преобразование переменной типа входной файловый поток к типуbool
(определено для классов потоков в STL). Если всё нормально, внутри блока работаем с потокомINdir
также, как со стандартнымcin
.Для полноты ощущений, в код хорошо бы добавить обработку ситуаций, когда с открытием файла что-то пошло не так. Тем более, что ты используешь два файла: входной и выходной, и при ошибке открытия входного файла, скорее всего, выходной файл открывать/создавать не имеет смысла. Обработку ошибочных ситуаций можно сделать разными способами (
if-else
, возбуждение и обработка исключений) и с различной логикой работы. Это уже зависит от того, как ты планируешь построить логику работы программы.Ещё один момент. По умолчанию конструктор файлового потока открывает файл в текстовом режиме. Ты планируешь работать с бинарным файлом из Excel (или я ошибаюсь?). Следовательно нужно использовать второй параметр конструктора:
Для чего нужны
на данном этапе мне не понятно. Поэтому без комментариев.
Добрый день. По факту я смог наворотить вот такой код. Он мне полностью понятен и я знаю как и что в нём работает.
Честно говоря дальше я затупил из-за переизбытка разнообразной информации. Входной файл у меня .xlsx Нагуглил что в начале этот файл нужно распаковать используя библиотеку zlib. А потом работать с распакованными данными.
Если вам будет проще понять для чего всё это опишу что в итоге программа должна на вход получать таблицу .xlsx парсить её и записывать в файл.
Отличная программа. Придраться можно только к форматированию исходного кода и включению лишних заголовков.
А вот парсить Экселовские таблицы и записывать в файл тебе, наверное, лучше на VBA из под того же Excel. Мне кажется, что с С++ ты времени потратишь гораздо больше.
Обязательно xlsx? С CSV намного проще будет работать.
selevit, CSV — это не спортивно! ))
Настоящий программист не будет связываться с текстовым форматом электронных таблиц. Тем более, что разделитель полей и десятичная точка в нём зависит от настроек локали операционной системы. Только xlsx, только хардкор!
Череп, не смог отделить сарказм от серьезных утверждений в твоем посте :)
Это, кстати, автоматически детектируется большинством редакторов.
Редакторы — это хорошо. Но если парсить CSV самописной программой... Причём сгенерирован CSV может быть на компе с одними настройками локали, а парситься будет — на компе с другими настройками. Ещё, помнится, там с ограничителями строк какая-то байда была... Так что тут тоже не всё так шоколадно.
В итоге получается задача текстового парсинга с плавающими условиями. При прочих равных, лично я бы реализовывал её НЕ на С/С++. А учитывая близость Эксела и примерно одинаковый уровень владения топикмейкером С++ и VBA, логичный совет: использовать VBA и не искать себе лишнего геморроя.
CSV часто используют для импорта и экспорта данных, наряду с XML. Обычно в этом случае формат файла детерминирован.
В CSV строки экранируются специфическим образом (кавычки экранируются кавычками) и это нужно учитывать. Уверен, что уже есть много готовых реализаций парсеров.
Могу с ходу выдать пример, когда необходимо использовать парсинг CSV в C++. Например, если нам нужно быстро делать импорт 50 миллионов записей из файла в БД. Обычно такие парсеры пишутся на скриптовых языках (PHP, Perl, Python), но при большом количестве данных иногда есть смысл написать это на плюсах.
XLSX-формат в этом случае будет огромным оверхедом. Да и не видел, чтобы VBA всерьез использовался где-то кроме макросов к продуктам MS Office.
Угу... Ради интереса, почитай в статью Википедии. И не могу не процитировать:
О чём я и говорил.
Не думаю, что перед топикмейкером стоит задача переноса 50 млн. записей из Excel в БД )) А для десятка тысяч записей скрипт на VBA под Excel — вполне потянет.
Собственно говоря, я это и имел ввиду, когда писал
Я так понимаю, перед ТС вообще никакой конкретной задачи не стоит. Задачка-то учебная, наверно.
Я так понимаю, что ТС уже давно забил на этот топик.
Для учебной задачи парсинг xlsx, imho, солжновато.