2008-09-10 4 views
38

Если вы пишете исполняемую программу из командной строки, вы часто хотите предложить пользователю несколько опций или флагов, а также, возможно, более одного аргумента. Я наткнулся на это много раз, но есть ли какой-то шаблон дизайна для прокрутки аргументов и отработки соответствующих функций?Что такое шаблон проектирования для обработки аргументов командной строки

Рассмотрим:

myprogram -f filename -d directory -r regex 

Как организовать код после извлечения аргументов, используя любые встроенные модули для вашего языка? (приветствуются ответы на конкретные языки, если это поможет вам сформулировать ответ)

+0

Это должно быть помечено как «язык-агностик», поскольку вопрос требует шаблон дизайна, а также предложения. – martinatime 2008-09-10 15:52:53

ответ

13

Я не знаю никаких документированных «шаблонов» для обработки.

Я считаю, что одной из самых старых библиотек/API для обработки аргументов является getopt. Googling «getopt» показывает много справочных страниц и ссылок на реализации.

Как правило, у меня есть служба настроек или настроек в моем приложении, с которой процессор аргументов знает, как с ним общаться. Аргументы затем переводятся на что-то в этой службе, чем приложение, чем запрос. Это может быть так же просто, как словарь настроек (например, строка с именем «filename»).

1

Я бы рекомендовал использовать библиотеку процессоров командной строки. Some Russian guy создал приличный, но их там много. Вы сэкономите некоторое время, чтобы сосредоточиться на цели своего приложения, а не на синтаксическом анализе командной строки!

+0

Мне нравится эта статья. Благодаря! :-) – craigmoliver 2017-02-10 15:24:51

0

Я использую Getopts::std и Getopts::long в Perl, а также Getopt функция в C. Это стандартизирует синтаксический анализ и формат параметров. Другие языки имеют разные механизмы для их обработки.

Надеется, что это помогает

0

Стандартная конструкция обычно следует, что Getopt делает, есть Getopt библиотеки для многих языков, .NET, Python, C, Perl, PHP и т.д.

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

This статья обсуждает его более подробно.

2

boost::program_options библиотека хорошо, если вы в C++ и имеют роскошь использовать Boost.

+0

Это хороший выбор. Эта библиотека немного сложна по сравнению со старым getopt, но позволяет также использовать файлы конфигурации (заменяя или интегрируя аргументы командной строки). – 2013-02-07 09:05:08

0

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

+0

Возможно, вы захотите обновить это в своем вопросе, а не здесь, о разъяснении. Он предназначен только для ответов. – rpattabi 2008-09-21 16:38:29

2

Предполагая, что у вас есть объект «config», который вы хотите установить с помощью флагов и подходящий синтаксический анализатор командной строки, который заботится о синтаксическом анализе командной строки и предоставляет постоянный поток параметров, здесь идет блок псевдокода

while (current_argument = cli_parser_next()) { 
    switch(current_argument) { 
     case "f": //Parser strips the dashes 
     case "force": 
      config->force = true; 
      break; 
     case "d": 
     case "delete": 
      config->delete = true; 
      break; 
     //So on and so forth 
     default: 
      printUsage(); 
      exit; 
    } 
} 
2

Я предпочитаю такие опции, как «-t текст» и «-i 44»; Мне не нравится «-fname» или «--very-long-argument = some_value».

И «-?», «-h» и «/ h» создают экран справки.

Вот как мой код выглядит:

int main (int argc, char *argv[]) 
    { int i; 
     char *Arg; 
     int ParamX, ParamY; 
     char *Text, *Primary; 

    // Initialize... 
    ParamX = 1; 
    ParamY = 0; 
    Text = NULL; 
    Primary = NULL; 

    // For each argument... 
    for (i = 0; i < argc; i++) 
     { 
     // Get the next argument and see what it is 
     Arg = argv[i]; 
     switch (Arg[0]) 
     { 
     case '-': 
     case '/': 
      // It's an argument; which one? 
      switch (Arg[1]) 
       { 
       case '?': 
       case 'h': 
       case 'H': 
        // A cry for help 
        printf ("Usage: whatever...\n\n"); 
        return (0); 
        break; 

       case 't': 
       case 'T': 
        // Param T requires a value; is it there? 
        i++; 
        if (i >= argc) 
        { 
        printf ("Error: missing value after '%s'.\n\n", Arg); 
        return (1); 
        } 

        // Just remember this 
        Text = Arg; 

        break; 

       case 'x': 
       case 'X': 
        // Param X requires a value; is it there? 
        i++; 
        if (i >= argc) 
        { 
        printf ("Error: missing value after '%s'.\n\n", Arg); 
        return (1); 
        } 

        // The value is there; get it and convert it to an int (1..10) 
        Arg = argv[i]; 
        ParamX = atoi (Arg); 
        if ((ParamX == 0) || (ParamX > 10)) 
        { 
        printf ("Error: invalid value for '%s'; must be between 1 and 10.\n\n", Arg); 
        return (1); 
        } 

        break; 

       case 'y': 
       case 'Y': 
        // Param Y doesn't expect a value after it 
        ParamY = 1; 
        break; 

       default: 
        // Unexpected argument 
        printf ("Error: unexpected parameter '%s'; type 'command -?' for help.\n\n", Arg); 
        return (1); 
        break; 
       } 

      break; 

     default: 
      // It's not a switch that begins with '-' or '/', so it's the primary option 
      Primary = Arg; 

      break; 
     } 
     } 

    // Done 
    return (0); 
    } 
4

Несколько замечаний по этому поводу ...

Во-первых, в то время как нет никаких шаблонов сами по себе, писать парсер является по существу механическое упражнение, поскольку с учетом грамматики парсер можно легко сгенерировать. Инструменты, такие как Bison и ANTLR, приходят на ум.

При этом генераторы синтаксического анализатора обычно являются излишними для командной строки. Таким образом, обычная картина заключается в том, чтобы написать один (как показали другие) несколько раз, пока вам не надоедает работа с утомительными деталями и найдите библиотеку, чтобы сделать это за вас.

Я написал один для C++, что позволяет экономить кучу усилий, Getopt Передает и делает хорошее использование шаблонов: TCLAP

+0

`` TCLAP`` - это фантастическая библиотека синтаксического анализа CLI. Предварительная синтаксическая настройка правил и извлечение после анализа синтаксического анализа `` argv`` очень полезна, интуитивно понятна и помогает разбить программу на правильные дискретные компоненты (IMHO). – Sean 2013-01-21 07:08:14

2

Я риффы на ANTLR ответа по mes5k. Этот link to Codeproject предназначен для статьи, в которой обсуждается ANLTR и используется шаблон посещения для реализации действий, которые вы хотите, чтобы приложение было выполнено. Он хорошо написан и заслуживает внимания.

12

Я думаю, что следующий ответ больше вдоль линий того, что вы ищете:

Вы должны смотреть на применение шаблона Pattern (шаблонный метод в «Design Patterns» [Gamma, эль-аль])

Короче говоря, это общая обработка выглядит следующим образом:

If the arguments to the program are valid then 
    Do necessary pre-processing 
    For every line in the input 
     Do necessary input processing 
    Do necessary post-processing 
Otherwise 
    Show the user a friendly usage message 

Короче говоря, реализовать класс ConsoleEngineBase, который имеет методы:

PreProcess() 
ProcessLine() 
PostProcess() 
Usage() 
Main() 

Затем создайте шасси, которое создает экземпляр экземпляра ConsoleEngine() и отправляет сообщение Main(), чтобы его выключить.

Чтобы увидеть хороший пример того, как применить это к консоли или командной строки программы обработки проверить по следующей ссылке: http://msdn.microsoft.com/en-us/magazine/cc164014.aspx

Пример находится в C#, но идеи легко реализовать в любой другой среде.

Вы бы посмотрели на GetOpt() как на часть, которая подходит для обработки аргументов (предварительная обработка).

Надеюсь, это поможет.

+1

рекомендуется для реализации концепций, а не реализации. Я чувствую, что это должен был быть выбранный ответ. – Plasmarob 2015-05-22 18:21:25

3

Ну, это старый пост, но я все равно хотел бы внести свой вклад.Вопрос был направлен на выбор шаблонов проектирования, однако я мог видеть много дискуссий о том, какую библиотеку использовать. Я проверил microsoft-ссылку в соответствии с lindsay, которая рассказывает о шаблоне шаблона шаблона для использования.

Однако я не уверен в этом сообщении. Цель шаблона шаблона состоит в том, чтобы определить шаблон, который будет реализован различными другими классами для обеспечения единообразного поведения. Я не думаю, что синтаксический анализ командной строки вписывается в нее.

Я предпочел бы использовать шаблон «Command». Этот шаблон лучше всего подходит для опций, управляемых меню.

http://www.blackwasp.co.uk/Command.aspx

так в вашем случае, -f, -d и -r становится все команды, которые имеют общий или отдельный приемник определен. Таким образом, в будущем можно определить большее количество приемников. Следующим шагом будет объединение этих обязанностей команд, если требуется цепочка обработки. Для чего я бы выбрал.

http://www.blackwasp.co.uk/ChainOfResponsibility.aspx

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

Смежные вопросы