Язык программирования C++. Вводный курс



Функция main(): разбор параметров командной строки - часть 4


/p>

  file_names.push_back( string( pchar ));

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

Слабость нашей реализации становится понятной, если пользователь небрежно относится к пробелам, разделяющим параметры. Скажем, ни одна из следующих двух строк не будет обработана:

prog - d dataOl

prog -oout_file dataOl

(Оба случая мы оставим для упражнений в конце раздела.)

Вот полный текст нашей программы. (Мы добавили инструкции печати для трассировки выполнения.)

#include <iostream>

 

#include <string>

#include <vector>

 

#include <ctype.h>

 

const char *const program_name = "comline";

const char *const program_version = "version 0.01 (08/07/97)";

 

inline void usage( int exit_value = 0 )

{

  // печатает отформатированное сообщение о порядке вызова

  // и завершает программу с кодом exit_value ...

 

  cerr << "порядок вызова:\n"

       << program_name << " "

       << "[-d] [-h] [-v] \n\t"

       << "[-o output_file] [-l limit] \n\t"

       << "file_name\n\t[file_name [file_name [ ... ]]]\n\n"

       << "где [] указывает на необязательность опции:\n\n\t"

       << "-h: справка.\n\t\t"

       << "печать этого сообщения и выход\n\n\t"

       << "-v: версия.\n\t\t"

       << "печать информации о версии программы и выход\n\n\t"

       << "-d: отладка.\n\t\t включает отладочную печать\n\n\t"

       << "-l limit\n\t\t"

       << "limit должен быть неотрицательным целым числом\n\n\t"

       << "-o ofile\n\t\t"

       << "файл, в который выводится результат\n\t\t"

       << "по умолчанию результат записывается на стандартный вывод\n\n"

       << "file_name\n\t\t"

       << "имя подлежащего обработке файла\n\t\t"

       << "должно быть задано хотя бы одно имя --\n\t\t"

       << "но максимальное число не ограничено\n\n"

       << "примеры:\n\t\t"

       << "$command chapter7.doc\n\t\t"

       << "$command -d -l 1024 -o test_7_8 "

       << "chapter7.doc chapter8.doc\n\n";

 

  exit( exit_value );

}

 

int main( int argc, char* argv[] )

{

  bool debug_on = false;

  bool ofile_on = false;

  bool limit_on = false;

  int limit = -1;

  string ofile;

  vector<string> file_names;

 

  cout << "демонстрация обработки параметров в командной строке:\n"

       << "argc: " << argc << endl;

 

  for ( int ix = 1; ix < argc; ++ix )

  {

    cout << "argv[ " << ix << " ]: "

         << argv[ ix ] << endl;

 

    char *pchar = argv[ ix ];

    switch ( pchar[ 0 ] )

    {

      case '-':

      {

        cout << "встретился \'-\'\n";

        switch( pchar[ 1 ] )

        {

          case 'd':

            cout << "встретилась -d: "

                 << "отладочная печать включена\n";

 

            debug_on = true;

            break;

 

          case 'v':

            cout << "встретилась -v: "

                 << "выводится информация о версии\n";

 

            cout << program_name

                 << " ::  "

                 << program_version

                 << endl;

 

            return 0;

 

          case 'h':

            cout << "встретилась -h: "

                 << "справка\n";

 

            // break не нужен: usage() завершает программу

            usage();

 

          case 'o':

            cout << "встретилась -o: выходной файл\n";

            ofile_on = true;

            break;

          case 'l':

            cout << "встретилась -l: "

                 << "ограничение ресурса\n";

 

            limit_on = true;

            break;

 

          default:

            cerr << program_name

                 << " : ошибка : "

                 << "неопознанная опция: - "

                 << pchar << "\n\n";

 

            // break не нужен: usage() завершает программу

            usage( -1 );

        }

        break;

      }

 

      default: // либо имя файла

        cout << "default: параметр без дефиса: "

             << pchar << endl;

 

        if ( ofile_on ) {

          ofile_on = false;

          ofile = pchar;

        }

        else

        if ( limit_on ) {

          limit_on = false;

          limit = atoi( pchar );

          if ( limit < 0 ) {

            cerr << program_name

                 << " : ошибка : "

                 << "отрицательное значение limit.\n\n";

 

            usage( -2 );

          }

        }

        else file_names.push_back( string( pchar ));

        break;

    }

  }

 

  if ( file_names.empty() ) {

    cerr << program_name

         << " : ошибка : "

         << "не задан ни один входной файл.\n\n";

    usage( -3 );

  }

 

  if ( limit != -1 )

    cout << "Заданное пользователем значение limit: "

         << limit << endl;

 

  if ( ! ofile.empty() )

    cout << "Заданный пользователем выходной файл: "

         << ofile << endl;

 

  cout << (file_names.size() == 1 ? "Файл, " : "Файлы, ")

       << "подлежащий(е) обработке:\n";

 

  for ( int inx = 0; inx < file_names.size(); ++inx )

    cout << "\t" << file_names[ inx ] << endl;

}

a.out -d -l 1024 -o test_7_8 chapter7.doc    chapters.doc

Вот трассировка обработки параметров командной строки:

демонстрация обработки параметров в командной строке:

argc: 8

argv[ 1 ]: -d

встретился '-'

встретилась -d: отладочная печать включена

argv[ 2 ]: -l

встретился '-'

встретилась -l: ограничение ресурса

argv[ 3 ]: 1024

default: параметр без дефиса: 1024

argv[ 4 ]: -o

встретился '-'

встретилась -o: выходной файл

argv[ 5 ]: test_7_8

default: параметр без дефиса: test_7_8

argv[ 6 ]: chapter7.doc

default: параметр без дефиса: chapter7.doc

argv[ 7 ]: chapter8.doc

default: параметр без дефиса: chapter8.doc

Заданное пользователем значение limit: 1024

Заданный пользователем выходной файл: test_7_8

Файлы, подлежащий(е) обработке:

        chapter7.doc

        chapter8.doc




Содержание  Назад  Вперед