LINUX.ORG.RU

Добавление сахарку в C++ для быстрого написания «скриптов»

 ,


1

1

Доброй ночи. Ищу способ добавления ещё большего количества синтаксического сахара в C++, чтобы можно было писать компактные и выразительные небольшие приложения. Скажем, в качестве замены простыни из Perl/Bash/Python.

Допускаю использование любых библиотек, хэдеров, и фреймворков, в том числе и построенных на boost и qt4/qt5 (без GUI).

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

Попытки сделать это через boost (в том числе и boost::filesystem) или через glibc выливаются в лапшу из кода с кучей дополнительных телодвижений.

Вот пример относительно простого способа прочитать конфиги в алфавитном порядке из указанной директории (самым приятным пока рассматриваю вариант с Qt5)

QDir dir(QString::fromStdString(path));
if(!dir.exists()) {
    std::cerr << path << " does not exist\n";
    return 1;
}

for(const QFileInfo &fileinfo : dir.entryInfoList(QDir::Files | QDir::Readable, QDir::Name)) {
    QFile file(fileinfo.absoluteFilePath());
    file.open(QIODevice::ReadOnly);
    if(!file.isOpen()) {
        std::cerr << "Can't open file: " << qPrintable(file.fileName()) << "\nReason: " << qPrintable(file.errorString()) << '\n';
        return 1;
    }
    // ...
}

Тем не менее, я считаю его многословным, ряд действий можно было бы упаковать в обёртки. Писать свою тоже можно, но вдруг уже кто-то сделал подобное.

У кого какие идеи?

★★★★★

Последнее исправление: Chaser_Andrey (всего исправлений: 5)
Ответ на: комментарий от anonymous

boost filesystem

Уже пробовал. Получается та же лапша. Серьёзно, на Qt код более компактный, проще и читабельнее.

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

из boost filesystem tutorial:

  path p (argv[1]);

  try
  {
    if (exists(p))
    {
      if (is_directory(p))      // is p a directory?
      {
        copy(directory_iterator(p), directory_iterator(),
          ostream_iterator<directory_entry>(cout, "\n"));
      }
    }
    else
      cout << p << " does not exist\n";
  }

  catch (const filesystem_error& ex)
  {
    cout << ex.what() << '\n';
  }
чего проще?

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

Так ведь проще, не?

QDir dir(argv[1]);
if(dir.exists())
    for(const QFileInfo &fileinfo : dir.entryInfoList(QDir::Files | QDir::Readable, QDir::Name)) {
        // do something with fileinfo.absoluteFilePath()
    }
else
    std::cout << argv[1] << " does not exist\n";

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

С моей точки зрения - примерно одинаково. Это потому, что я много кода писал, и много читал (хотел бы развидеть, да не могу).

Оба варианта, и кутейный, и бустовый, нетрудно свести к вышесказанному

for (auto  file : dirFiles(path))
    {
        // ...
    }
, что, по-моему, не длиннее, чем на любом языке, хоть питон, хоть баш.

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

Кстати, на заметку entryInfoList и entryList безумно тормозные функции. Относительно большое количество файлов (2000-3000) уже вычитывают долго.

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

Тот же boost::filesystem возвращает найденные сущности в директории в неопределенном порядке, так что и там надо писать код, чтобы сохранить всё найденное в векторе, который потом нужно посортировать, и только тогда можно обрабатывать. Это важно в конфигах, где имеет значение порядок их включения (например, с префиксами 00, 01, 10 и т.д.).

Впрочем, всегда есть профилирование, которое позволит убедиться, что узкое место - именно в entryInfoList и в entryList.

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

В твоем примере нет сортировки по имени, например. Это ещё пару строчек и дополнительный цикл обхода отсортированого вектора.

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

Если реально есть время - то напиши, сначала код, как тебе было бы удобно записывать свои манипуляции (лучше сразу оформленный в виде теста), а потом запили имплементацию.

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

Ну лично я может и извращенец, но бустовые интерфейсы мне нравяться больше. Посмотри ещё на Poco, но там оно не сильно от Qt отличается.

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

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

А почему вектор? Что мешает в set сложить?:) В том же бусте - никаких проблем это не вызовет :)

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

зачем строчки, зачем циклы...

for (auto  file : dirFiles(path).sorted(byName))
    {
        // ...
    }

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