Как проанализировать параметры командной строки в C++? [дубликат]

Механизм Item / ItemLoader соответствует вашим целям. Что-то вроде:

Определите элемент для строки данных:

class DataRowItem(scrapy.Item):
     current_time = scrapy.Field()
     firstitem = scrapy.Field()
     ...

Затем объявите соответствующий ItemLoader:

class DataRowItemLoader(scrapy.ItemLoader):
    default_item_class = DataRowItem
    default_output_processor = TakeFirst()

В функции разбора:

[112 ]

И затем сериализовать элементы в CSV, используя, например, этот метод: Экспорт CSV-файла из Scrapy (не через командную строку)

183
задан Community 23 May 2017 в 02:10
поделиться

5 ответов

Boost.Program_options должен помочь

84
ответ дан 23 November 2019 в 06:00
поделиться

Предложения для boost :: program_options и GNU getopt являются хорошими.

Однако, для простых параметров командной строки я обычно использую std :: find

. Например, чтобы прочитать имя файла после аргумента командной строки -f . Вы также можете просто определить, была ли передана опция из одного слова, например -h для помощи.

#include <algorithm>

char* getCmdOption(char ** begin, char ** end, const std::string & option)
{
    char ** itr = std::find(begin, end, option);
    if (itr != end && ++itr != end)
    {
        return *itr;
    }
    return 0;
}

bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
    return std::find(begin, end, option) != end;
}

int main(int argc, char * argv[])
{
    if(cmdOptionExists(argv, argv+argc, "-h"))
    {
        // Do stuff
    }

    char * filename = getCmdOption(argv, argv + argc, "-f");

    if (filename)
    {
        // Do interesting things
        // ...
    }

    return 0;
}

На что следует обратить внимание при таком подходе, вы должны использовать std :: strings в качестве значения для std :: find в противном случае выполняется проверка на равенство значений указателя.


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

class InputParser{
    public:
        InputParser (int &argc, char **argv){
            for (int i=1; i < argc; ++i)
                this->tokens.push_back(std::string(argv[i]));
        }
        /// @author iain
        const std::string& getCmdOption(const std::string &option) const{
            std::vector<std::string>::const_iterator itr;
            itr =  std::find(this->tokens.begin(), this->tokens.end(), option);
            if (itr != this->tokens.end() && ++itr != this->tokens.end()){
                return *itr;
            }
            static const std::string empty_string("");
            return empty_string;
        }
        /// @author iain
        bool cmdOptionExists(const std::string &option) const{
            return std::find(this->tokens.begin(), this->tokens.end(), option)
                   != this->tokens.end();
        }
    private:
        std::vector <std::string> tokens;
};

int main(int argc, char **argv){
    InputParser input(argc, argv);
    if(input.cmdOptionExists("-h")){
        // Do stuff
    }
    const std::string &filename = input.getCmdOption("-f");
    if (!filename.empty()){
        // Do interesting things ...
    }
    return 0;
}
233
ответ дан 23 November 2019 в 06:00
поделиться

You can use GNU GetOpt (LGPL) or one of the various C++ ports, such as getoptpp (GPL).

A simple example using GetOpt of what you want (prog [-ab] input) is the following:

// C Libraries:
#include <string>
#include <iostream>
#include <unistd.h>

// Namespaces:
using namespace std;

int main(int argc, char** argv) {
    int opt;
    string input = "";
    bool flagA = false;
    bool flagB = false;

    // Retrieve the (non-option) argument:
    if ( (argc <= 1) || (argv[argc-1] == NULL) || (argv[argc-1][0] == '-') ) {  // there is NO input...
        cerr << "No argument provided!" << endl;
        //return 1;
    }
    else {  // there is an input...
        input = argv[argc-1];
    }

    // Debug:
    cout << "input = " << input << endl;

    // Shut GetOpt error messages down (return '?'): 
    opterr = 0;

    // Retrieve the options:
    while ( (opt = getopt(argc, argv, "ab")) != -1 ) {  // for each option...
        switch ( opt ) {
            case 'a':
                    flagA = true;
                break;
            case 'b':
                    flagB = true;
                break;
            case '?':  // unknown option...
                    cerr << "Unknown option: '" << char(optopt) << "'!" << endl;
                break;
        }
    }

    // Debug:
    cout << "flagA = " << flagA << endl;
    cout << "flagB = " << flagB << endl;

    return 0;
}
33
ответ дан 23 November 2019 в 06:00
поделиться

I'd recommend boost::program_options if you can use the Boost lib.

There's nothing specific in STL nor in the regular C++/C runtime libs.

3
ответ дан 23 November 2019 в 06:00
поделиться

Попробуйте библиотеку CLPP. Это простая и гибкая библиотека для разбора параметров командной строки. Только для заголовков и кроссплатформенная. Использует только библиотеки ISO C++ и Boost C++. IMHO она проще, чем Boost.Program_options.

Библиотека: http://sourceforge.net/projects/clp-parser

26 октября 2010 - новый релиз 2.0rc. Исправлено множество ошибок, полный рефакторинг исходного кода, исправлена документация, примеры и комментарии.

2
ответ дан 23 November 2019 в 06:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: