// 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