// break не нужен: usage() вызывает exit()

usage();

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

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

// если ofi1e_on==true,

// следующий параметр - имя выходного файла

bool ofi1e_on = false;

// если ofi1e_on==true,

// следующий параметр - максимальный размер

bool limit_on = false;

Вот обработка опций -l и -o в нашей инструкции switch:

case 'l':

limit_on = true;

break;

case 'o':

ofile_on = true;

break;

Встретив строку, не начинающуюся с дефиса, мы с помощью переменных состояния можем узнать ее содержание:

// обработаем максимальный размер для опции -1

// имя выходного файла для -o

// имена входных файлов ...

default: {

// ofile_on включена, если -o встречалась

if ( ofile_on ) {

// обработаем имя выходного файла

// выключим ofile_on

}

else if ( limit_on ) { // если -l встречалась

// обработаем максимальный размер

// выключим limit_on

} else {

// обработаем имя входного файла

}

}

Если аргумент является именем выходного файла, сохраним это имя и выключим ofile_on:

if ( ofile_on ) {

ofile_on = false;

ofile = pchar;

}

Если аргумент задает максимальный размер, мы должны преобразовать строку встроенного типа в представляемое ею число. Сделаем это с помощью стандартной функции atoi(), которая принимает строку в качестве аргумента и возвращает int (также существует функция atof(), возвращающая double). Для использования atoi() включим заголовочный файл ctype.h. Нужно проверить, что значение максимального размера неотрицательно и выключить limit_on:

// int limit;

else

if ( limit_on ) {

limit_on = false;

limit = atoi( pchar );

if ( limit 0 ) {

cerr program_name "::"

program_version " : error: "

"negative value for limit.\n\n";

usage( -2 );

}

}

Если обе переменных состояния равны 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

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

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

argv[ 3 ]: 1024

Перейти на страницу:

Похожие книги