Функция 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