LINUX.ORG.RU

Парсинг параметров из txt файла C++

 


0

3

Доброго дня всем. Можете пожалуйста подсказать, помочь, направить на путь истинный так сказать. Столкнулся с проблемой, вроде бы как в весьма тривиальной задачке. Это всё разумеется из-за отсутствия знаний, которые стремлюсь улучшить. В общем, есть файл “file.txt”, в нем примерно следующего типа строки: Nik = CK Eth = 1500

И мне нужно найти нужную мне строку и оттуда захватить значение (например, на что равен Nik).

На текущий момент я реализовал через ifstream открытие файла, при помощи getline в цикле я из файла в string закидываю. Как вариант решение предполагал следующее: string через push_back закинуть в vector, потом в векторе каждую строку разделить до “=” и проверять на совпадение (через std::find???) и если совпадение есть, то захватить то, что идёт после “=” (как именно??). Правильное ли это решение? Можете помочь как лучше всего это сделать?

Ответ на: комментарий от bugfixer

… И опять преувеличиваете - писать придется не меньше. Либо придется обегать какое нибудь DOM-like tree которое выплюнет сторонний парсер …

Определенно меньше, в зависимости от выбранной библиотеки и ее возможностей. Какое нибудь DOM-like tree как раз должно быть «в коробке». Остается только сделать биндинг ключей на переменные.

либо долго разбираться с доками на тему как привязать конкретные переменные

Никогда проблем не вызывало), при наличии документации и тестов. И если тащить сторонние проекты, то как минимум тесты там должны быть.

Быстрее в runtime точно не будет

Старт программы не является хотспотом. Парсинг конфига, вряд ли, будет узким местом.

За универсальность нужно платить. А главное - ради чего все эти усилия?

Плата не сильно высока. Если у программы появляется конфиг, то это значит что в опции уже все не влезает или там будет помойка. И что бы в конфиге не образовалось помойка, его следует сделать по уму. Решение на коленке абсолютно плоское, даже ini-файл на секции разбит. «На коленке» это будет решаться десятиэтажным неймингом ключей. И хорошо если автор окажется организованным и будет придерживаться какого-то стиля и следить за ним. К тому же оно не прозрачное. Что если в конфиге key1 = value будет 10 раз повторятся с разными value? Очевидно, будет зависить от того как оно в // процессим остаток строки так написано, что ИМХО «квадратно» выглядит. Мы точно уверены, что в // процессим остаток строки так тоже корректная логика на 5 ключей key2? А если у меня какя-то сущность от 3-х ключей зависит? Тут if (key == "key1") {...} уже не обойтись. Мне же все просто обещали.

PRN
()
Ответ на: комментарий от bugfixer

Не проигрывает точно (даже буковок ровно столько же). Когда выигрывает - я уже писал.

Вроде, уже выяснили что ждать там COW не стоит))

… если более новый не дает преимущества в скорости в runtime

Очевидный факт, но даже при прочих равных удобство в разработке тоже неплохой повод обновить стандарт/компилятор.

PRN
()
Ответ на: комментарий от PRN

Определенно меньше

Вы реально считаете что мне больше буковок придется написать чтобы с десяток чисел вытянуть из plain text файла?

тащить сторонние проекты

Как только Вы это сделаете Вы станете заложником авторов этой библиотечки, ну или подвяжетесь её мантэйнить для своих нужд. Опять же - зачем?

Старт программы не является хотспотом. Парсинг конфига, вряд ли, будет узким местом.

С одной стороны - я об этом уже говорил, ну а с другой - если у Вас сотни и тысячи instances взлетают каждый день, то можно и попариться за performance.

Плата не сильно высока.

Спорное утверждение.

Если у программы появляется конфиг, то это значит что в опции уже все не влезает или там будет помойка.

И ещё это означает что у Вас появляется одно место контролирующее все instances, и не надо править параметры в сотне мест. Причем прелесть в том что изменения будут подхватываться при «автоматическом растарте» после «падения»

Решение на коленке абсолютно плоское

Какая разница если этого хватает?

тоже корректная логика на 5 ключей key2

Вот здесь не понял: Вы хотите много key2 в конфиге иметь?

Мне же все просто обещали.

Я топлю за решение сложность которого адекватна задаче. Потребности OP предложенное с лихвой покрывает. Вы почему то норовите стрелять из пушки по воробьям.

ПыСы. И таки я знаю о чем говорю - я не один десяток таких парсеров написал (часть - с довольно сложным синтаксисом), и по долгу службы приходиться мантэйнить много-километровые конфиги тоже. Неужели Вы думаете я сам себе враг?

bugfixer ★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от PRN

Очевидный факт, но даже при прочих равных удобство в разработке тоже неплохой повод обновить стандарт/компилятор.

Вот представьте себе что у Вас есть курочка несущая золотые яйца, а тут к Вам приходит производитель клетки и говорит: «Знаете, мы такие больше не выпускаем, и проволока у нас теперь не стальная, а платиновая. Но так как Вы наш хороший клиент - так и быть - мы Вам дадим новую клетку бесплатно». А Вы даже не знаете - вдруг Вашей курочке новая клетка не понравится и она нестись перестанет. И смысл таких upgrades? Всё должно быть обоснованно, Вы должны знать зачем и почему Вы делаете то или иное изменение. Не всё то солнышко что встаёт. Надеюсь доступно объяснил…

bugfixer ★★★★
()
Ответ на: комментарий от bugfixer

И таки я знаю о чем говорю - я не один десяток таких парсеров написал

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

приходиться мантэйнить много-километровые конфиги тоже

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

Неужели Вы думаете я сам себе враг?

Мы все себе не враги (по крайней мере бОльшая часть из нас).

PRN
()
Ответ на: комментарий от PRN

Я даже не сомневаюсь в том что еще не один десяток таких же велосипедов будет написан.

А я в свою очередь уверен что ни один сторонний парсер не будет решать наши задачи лучше чем наш собственный со всех точек зрения - ни по гибкости, ни по скорости, ни по трудозатратам при необходимости изменений. И как бы Вам не хотелось называть это «велосипедом» - это самое простое решение которое работает. Если Вам так нравится самому себе создавать дополнительные сложности - да ради бога, вот только «продать» такое решение мне Вам скорее всего ни при каких раскладах не удастся.

Только это очень на NIH похоже

Что есть «NIH»?

Попробуйте отдать кому-то кто в код заглянуть не может

У нас к счастью таких немного. Но таки да - если бы софт был не для внутреннего потребления пришлось бы документировать гораздо подробнее. А километровость (к сожалению наверное) - объективная производственная необходимость, если бы что то можно было порезать или выкинуть - мы бы давно это уже сделали.

bugfixer ★★★★
()
Ответ на: комментарий от PRN

Все же лучше пользоваться накопленным опытом, а не изобретать велосипед с нуля.

Неплохой контр-пример в голову пришёл. Предположим Вы подвязались на библиотечку X, и всё даже вроде как удобно и работает. А потом Вас озаряет что существенную часть Вашего конфига можно (и нужно) генерировать автоматически каждый день скриптами (например). И логичное решение в виде «сишного» #include my_automatically_generated_file библиотечкой не поддерживается. Ваши действия?

Это в поддержку моего тезиса о

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

bugfixer ★★★★
()
Ответ на: комментарий от bugfixer

ни один сторонний парсер не будет решать наши задачи лучше чем наш собственный … по скорости …

Расскажите, пожалуйста, случаи из жизни когда Вы упёрлись в скорость при загрузке конфига. Неужели такое бывает? И неужели бывают случаи, когда при загрузке конфига надо было сэкономить 3 байта в ОЗУ?

Так то понятно, что для утилиты на C++, которой пользуется один человек, любой формат конфига и парсера подойдёт. Тут велосипед выигрывает. Для других случаев лучше xml или json, а также готовые библиотеки.

Kogrom
()
Ответ на: комментарий от Kogrom

Расскажите, пожалуйста, случаи из жизни когда Вы упёрлись в скорость при загрузке конфига. Неужели такое бывает?

Не то что бы упёрся-упёрся, но когда у Вас пара сотен instances примерно в одно и тоже время взлетают на каждой машинке, сэкономить пару секунд на каждом и уменьшить стресс на CPU - мелочь а приятно.

что для утилиты на C++

В нашем случае не утилитка, а серверный модуль.

которой пользуется один человек

Ну как один - у нас десятки сотрудников так или иначе вовлечены в поддержку этих конфигов, я бы сказал.

Для других случаев лучше xml или json

Считаю и то и другое крайне непрактичным, по многим причинам (в том числе удобство редактирования, просмотр diffs, etc). Ничего лучше plain text в этом смысле пока ещё не придумали. Имеется крайне негативный опыт с конфигами в xml (тот про который я рассказываю разросся примерно до 300kb на текущий момент, включая куски которые генерятся автоматически), так жалею что в какой то момент решили именно его использовать конкретно в этом месте.

bugfixer ★★★★
()
Последнее исправление: bugfixer (всего исправлений: 2)
Ответ на: комментарий от bugfixer

уменьшить стресс на CPU - мелочь а приятно

Пусть напрягается. Важнее уменьшение стресса разработчика.

Считаю и то и другое крайне непрактичным, по многим причинам (в том числе удобство редактирования, просмотр diffs, etc).

Тут от задачи зависит. Но если нет вложенности и нужно подстроиться под diff, то можно просто csv взять.

С другой стороны, можно использовать в конфиге один json-словарь и отформатировать его удобно для diff. Некая избыточность будет только в кавычках. Ну и с xml можно извратиться и всё через атрибуты одного элемента записать.

у нас десятки сотрудников так или иначе вовлечены в поддержку этих конфигов

Тогда лучше через GUI настраивать, чтобы ничего не попортили. И тогда опять формат лучше стандартный, ибо где GUI, там обычно и поддержка стандартных форматов есть.

Kogrom
()
Ответ на: комментарий от menangen

Да что с вами не так, пятизвездочные дегенераты? Человек задает вопрос уровня 2*2, так ему один Bison советует, второй Boost-ом тычет, третий какой-то клубок сишных либ вида швейцарский нож выдает. Максимум что нужно ТС на данный момент это std::string::find и какой-нибудь std::map<string, string>. Пускай учится программировать.

anonymous
()
Ответ на: комментарий от anonymous

Так можно дотрепаться, что зачем либы, зачем C++, пусть учится писать на Си, а лучше на ассемблере. Свои велосипеды к сердцу ближе, это да

menangen ★★★★★
()
Ответ на: комментарий от Kogrom

Тут от задачи зависит.

Вот. Я уже, если честно, устал повторять что сложность решения должна быть адекватна задаче. Не надо стрелять из пушки по воробьям и/или кодировать «на будущее».

Тогда лучше через GUI настраивать, чтобы ничего не попортили.

Ой не, ещё и гуйню писать / поддерживать, нафиг нафиг. Да и не особо жизнеспособно оно если у Вас в production одновременно живёт несколько постоянно обновляющихся версий одного и того же модуля, со слегка различающимися наборами параметров (которые тоже постоянно появляются новые, а старые постепенно отмирают). Тут я не вижу другого способа кроме как ручками.

чтобы ничего не попортили.

Иногда конечно портят, да, бывает. Поэтому есть своя внутренняя система отслеживания всех изменений (включая конфигурационные, я бы сказал что они не менее важны чем изменения в коде), свой operations dept который мониторит систему 24x7 и начинает вызванивать людей ответственных за тот или иной модуль если что то пошло не так, итд. Плюс не будете Вы всем подряд допуск в production давать, а те у кого он есть должны более менее понимать что они делают и трезво оценивать риски.

bugfixer ★★★★
()
Ответ на: комментарий от anonymous

Да что с вами не так … Пускай учится программировать.

Один из первых адекватных комментариев. Полностью солидарен.

bugfixer ★★★★
()
Ответ на: комментарий от anonymous

Да что с вами не так, пятизвездочные дегенераты?

Вероятно, влияние языков типа Java и Python. В питоне даже без либ будет просто split, strip и в словарь. А в си++ find, substr, substr, затем какой-нибудь хитровывернутый erase с итераторами и лямбдами, чтобы лишние пробелы убрать, а уже потом в словарь. Вот и хочется найти что-то простое как в питоне.

Kogrom
()
Ответ на: комментарий от Kogrom

А в си++ find, substr, substr …

И даже это лишнее всё. Любой istream (istringstream в частности) очень успешно борется с пропуском пробелов и делает tokenizing. До тех пор пока Вам shell-like escaping не приспичило делать - всё тривиально дальше некуда.

bugfixer ★★★★
()
Ответ на: комментарий от bugfixer

Да. Лишь бы пробела внутри ключа или значения не было.

Kogrom
()
Ответ на: комментарий от Kogrom

ни один сторонний парсер не будет решать наши задачи лучше чем наш собственный … по скорости …

Расскажите, пожалуйста, случаи из жизни когда Вы упёрлись в скорость при загрузке конфига. Неужели такое бывает? И неужели бывают случаи, когда при загрузке конфига надо было сэкономить 3 байта в ОЗУ?

Кстати, знаете когда это бывает критично? Если Вам нужно уметь перечитывать конфиги on-the-fly (по сигналу например), и Вы оперируете в мире где милли, иногда микро, а совсем иногда даже наносекунды имеют значение. Такое бывает, да.

bugfixer ★★★★
()
Ответ на: комментарий от menangen

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

anonymous
()
Ответ на: комментарий от anonymous

Ассемблер в 21 веке, положим, уже особо ни к чему

Ну, вообще говоря тем кто серьёзно программирует (ну или хотя бы претендует на то что серьёзно программирует) его рекомендуется уметь хотя бы читать, дабы понимать во что примерно разворачивается та или иная языковая конструкция, и почему версия A быстрее/медленнее версии Б. Помимо того что это очень познавательно, это также большое преимущество компилируемых непосредственно в объектники языков («я щитаю») - в той же Java все заложники JVM и никогда не знают что именно оно там делает «under the hood». А так чтобы писать - это да, давно ничего кроме маленьких асмовых вставочек в особо узких местах не видел. Мои 2 цента.

bugfixer ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.