Выбрать главу

}

Если обе переменных состояния равны false, у нас есть имя входного файла. Сохраним его в векторе строк:

else

file_names.push_back( string( pchar ));

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

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

prog - d dataOl

prog -oout_file dataOl

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

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

#include

#include

#include

#include

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 file_names;

cout

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

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

argc: 8

argv[ 1 ]: -d

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

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

argv[ 2 ]: -l

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

встретилась -class="underline" ограничение ресурса

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

7.8.1. Класс для обработки параметров командной строки

Чтобы не перегружать функцию main() деталями, касающимися обработки параметров командной строки, лучше отделить этот фрагмент. Можно написать для этого функцию. Например:

extern int parse_options( int arg_count, char *arg_vector );

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

// ...

int option_status;

option_status = parse_options( argc, argv );

// ...

}

Как вернуть несколько значений? Обычно для этого используются глобальные объекты, которые не передаются ни в функцию для их обработки, ни обратно. Альтернативной стратегией является инкапсуляция обработки параметров командной строки в класс.

Данные-члены класса представляют собой параметры, заданные пользователем в командной строке. Набор открытых встроенных функций-членов позволяет получать их значения. Конструктор инициализирует параметры значениями по умолчанию. Функция-член получает argc и argv в качестве аргументов и обрабатывает их:

#include

#include

class CommandOpt {

public:

CommandOpt() : _limit( -1 ), _debug_on( false ) {}

int parse_options( int argc, char *argv[] );

string out_file() { return _out_file; }

bool debug_on() { return _debug_on; }

int files() { return _file_names.size(); }

string& operator[]( int ix );

private:

inline void usage( int exit_value = 0 );

bool _debug_on;

int _limit;

string _out_file;

vector _file_names;

static const char *const program_name;

static const char *const program_version;

};

Так выглядит модифицированная функция main():

#include "CommandOpt.h"

int main( int argc, char "argv[] ) {

// ...

CommandOpt com_opt;

int option_status;

opttion_status = com_opt. parse_options (argc, argv);

// ...

}

Упражнение 7.15

Добавьте обработку опций -t (включение таймера) и -b (задание размера буфера bufsize). Не забудьте обновить usage(). Например:

prog -t -b 512 dataO

Упражнение 7.16

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

Упражнение 7.17

Наша реализация не может различить лишний пробел между дефисом и опцией: