Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Командная строка аргументов
Системные средства, на которые опирается реализация язы- ка "с", позволяют передавать командную строку аргументов или параметров начинающей выполняться программе. Когда функция MAIN вызывается к исполнению, она вызывается с двумя аргу- ментами. Первый аргумент (условно называемый ARGC) указывает число аргументов в командной строке, с которыми происходит обращение к программе; второй аргумент (ARGV) является ука- зателем на массив символьных строк, содержащих эти аргумен- ты, по одному в строке. Работа с такими строками - это обыч- ное использование многоуровневых указателей. Самую простую иллюстрацию этой возможности и необходимых при этом описаний дает программа ECHO, которая просто печа- тает в одну строку аргументы командной строки, разделяя их пробелами. Таким образом, если дана команда
ECHO HELLO, WORLD
то выходом будет
HELLO, WORLD
по соглашению ARGV[0] является именем, по которому вызывает- ся программа, так что ARGC по меньшей мере равен 1. В приве- денном выше примере ARGC равен 3, а ARGV[0], ARGV[1] и ARGV[2] равны соответственно "ECHO", "HELLO," и "WORLD". Первым фактическим агументом является ARGV[1], а последним - ARGV[ARGC-1]. Если ARGC равен 1, то за именем программы не следует никакой командной строки аргументов. Все это показа- но в ECHO:
MAIN(ARGC, ARGV) /* ECHO ARGUMENTS; 1ST VERSION */ INT ARGC; CHAR *ARGV[]; \( INT I;
FOR (I = 1; I < ARGC; I++) PRINTF("%S%C", ARGV[I], (I<ARGC-1)? ' ': '\N'); \)
Поскольку ARGV является указателем на массив указателей, то существует несколько способов написания этой программы, ис- пользующих работу с указателем, а не с индексацией массива. Мы продемонстрируем два варианта.
MAIN(ARGC, ARGV) /* ECHO ARGUMENTS; 2ND VERSION */ INT ARGC; CHAR *ARGV[]; \( WHILE (--ARGC > 0) PRINTF("%S%C",*++ARGV, (ARGC > 1)? ' ': '\N'); \)
Так как ARGV является указателем на начало массива строк-ар- гументов, то, увеличив его на 1 (++ARGV), мы вынуждаем его указывать на подлинный аргумент ARGV[1], а не на ARGV[0]. Каждое последующее увеличение передвигает его на следующий аргумент; при этом *ARGV становится указателем на этот аргу- мент. одновременно величина ARGC уменьшается; когда она об- ратится в нуль, все аргументы будут уже напечатаны. Другой вариант:
MAIN(ARGC, ARGV) /* ECHO ARGUMENTS; 3RD VERSION */ INT ARGC; CHAR *ARGV[]; \( WHILE (--ARGC > 0) PRINTF((ARGC > 1)? "%S": "%S\N", *++ARGV); \)
Эта версия показывает, что аргумент формата функции PRINTF может быть выражением, точно так же, как и любой другой. Та- кое использование встречается не очень часто, но его все же стоит запомнить. Как второй пример, давайте внесем некоторые усовершенст- вования в программу отыскания заданной комбинации символов из главы 4. Если вы помните, мы поместили искомую комбинацию глубоко внутрь программы, что очевидно является совершенно неудовлетворительным. Следуя утилите GREP системы UNIX, да- вайте изменим программу так, чтобы эта комбинация указыва- лась в качестве первого аргумента строки.
#DEFINE MAXLINE 1000
MAIN(ARGC, ARGV) /* FIND PATTERN FROM FIRST ARGUMENT */ INT ARGC; CHAR *ARGV[]; \( CHAR LINE[MAXLINE];
IF (ARGC!= 2) PRINTF ("USAGE: FIND PATTERN\N"); ELSE WHILE (GETLINE(LINE, MAXLINE) > 0) IF (INDEX(LINE, ARGV[1] >= 0) PRINTF("%S", LINE); \)
Теперь может быть развита основная модель, иллюстрирую- щая дальнейшее использование указателей. Предположим, что нам надо предусмотреть два необязательных аргумента. Один утверждает: "напечатать все строки за исключением тех, кото- рые содержат данную комбинацию", второй гласит: "перед каж- дой выводимой строкой должен печататься ее номер".
Общепринятым соглашением в "с"-программах является то, что аргумент, начинающийся со знака минус, вводит необяза- тельный признак или параметр. Если мы, для того, чтобы сооб- щить об инверсии, выберем -X, а для указания о нумерации нужных строк выберем -N("номер"), то команда
FIND -X -N THE
при входных данных
NOW IS THE TIME FOR ALL GOOD MEN TO COME TO THE AID OF THEIR PARTY.
Должна выдать
2:FOR ALL GOOD MEN
Нужно, чтобы необязательные аргументы могли располагать- ся в произвольном порядке, и чтобы остальная часть программы не зависела от количества фактически присутствующих аргумен- тов. в частности, вызов функции INDEX не должен содержать ссылку на ARGV[2], когда присутствует один необязательный аргумент, и на ARGV[1], когда его нет. Более того, для поль- зователей удобно, чтобы необязательные аргументы можно было объединить в виде:
FIND -NX THE
вот сама программа:
#DEFINE MAXLINE 1000
MAIN(ARGC, ARGV) /* FIND PATTERN FROM FIRST ARGUMENT */ INT ARGC; CHAR *ARGV[]; \( CHAR LINE[MAXLINE], *S; LONG LINENO = 0; INT EXCEPT = 0, NUMBER = 0; WHILE (--ARGC > 0 && (*++ARGV)[0] == '-') FOR (S = ARGV[0]+1; *S!= '\0'; S++) SWITCH (*S) \( CASE 'X': EXCEPT = 1; BREAK;
CASE 'N': NUMBER = 1; BREAK; DEFAULT: PRINTF("FIND: ILLEGAL OPTION %C\N", *S); ARGC = 0; BREAK; \) IF (ARGC!= 1) PRINTF("USAGE: FIND -X -N PATTERN\N"); ELSE WHILE (GETLINе(LINE, MAXLINE) > 0) \( LINENO++; IF ((INDEX(LINE, *ARGV) >= 0)!= EXCEPT) \ IF (NUMBER) PRINTF("%LD: ", LINENO); PRINTF("%S", LINE); \) \) \)
Аргумент ARGV увеличивается перед каждым необязательным аргументом, в то время как аргумент ARGC уменьшается. если нет ошибок, то в конце цикла величина ARGC должна равняться 1, а *ARGV должно указывать на заданную комбинацию. Обратите внимание на то, что *++ARGV является указателем аргументной строки; (*++ARGV)[0] - ее первый символ. Круглые скобки здесь необходимы, потому что без них выражение бы приняло совершенно отличный (и неправильный) вид *++(ARGV[0]). Дру- гой правильной формой была бы **++ARGV.
|