Наши рассуждения здесь касались целых значений, однако чаще массивы указателей используются для работы со строками символов, различающимися по длине, как это было в функции month_name . Сравните определение массива указателей и соответствующий ему рисунок:
char *name[] = {"Неправильный месяц", "Янв", "Февр", "Март"};
с объявлением и рисунком для двумерного массива:
char aname[][15] = {"Неправ. месяц", "Янв", "Февр", "Март"};
Упражнение 5.9. Перепишите программы day_of_year и month_day , используя вместо индексов указатели.
5.10 Аргументы командной строки
В операционной среде, обеспечивающей поддержку Си, имеется возможность передать аргументы или параметры запускаемой программе с помощью командной строки. В момент вызова main получает два аргумента. В первом, обычно называемом argc (сокращение от argument count ), стоит количество аргументов, задаваемых в командной строке. Второй, argv (от argument vector ), является указателем на массив символьных строк, содержащих сами аргументы. Для работы с этими строками обычно используются указатели нескольких уровней.
Простейший пример - программа echo ("эхо"), которая печатает аргументы своей командной строки в одной строчке, отделяя их друг от друга пробелами. Так, команда
echo Здравствуй, мир!
Напечатает
Здравствуй, мир!
По соглашению argv[0] есть имя вызываемой программы, так что значение argc никогда не бывает меньше 1. Если argc равен 1, то в командной строке после имени программы никаких аргументов нет. В нашем примере argc равен 3, и соответственно argv[0] , argv[1] и argv[2] суть строки "echo" , "Здравствуй," и "мир! ". Первый необязательный аргумент - это argv[1] , последний - argv[argc-1] . Кроме того, стандарт требует, чтобы argv[argc] всегда был пустым указателем.
Первая версия программы echo трактует argv как массив символьных указателей.
#include ‹stdio.h›
/* эхо аргументов командной строки: версия 1 */
main(int argc, char *argv[])
{
int i;
for (i = 1; i ‹ argc; i++)
printf("%s%s", argv[i], (i ‹ argc-1) ? " " : ");
printf("\n");
return 0;
}
Так как argv - это указатель на массив указателей, мы можем работать с ним как с указателем, а не как с индексируемым массивом. Следующая программа основана на приращении argv , он приращивается так, что его значение в каждый отдельный момент указывает на очередной указатель на char ; перебор указателей заканчивается, когда исчерпан argc .
#include ‹stdio.h›
/* эхо аргументов командной строки; версия 2 */
main(int argc, char *argv[])
{
while (--argc › 0)
printf("%s%s", *++argv, (argc › 1) ? " " : ");
print f("\n");
return 0;
}
Аргумент argv - указатель на начало массива строк аргументов. Использование в ++argv префиксного оператора ++приведет к тому, что первым будет напечатан argv[1] ,а не argv[0] . Каждое очередное приращение указателя дает нам следующий аргумент, на который указывает *argv . В это же время значение argc уменьшается на 1, и, когда оно станет нулем, все аргументы будут напечатаны. Инструкцию printf можно было бы написать и так:
printf((argc › 1)? "%s ": "%s", *++argv);
Как видим, формат в printf тоже может быть выражением.
В качестве второго примера возьмем программу поиска образца, рассмотренную в параграфе 4.1, и несколько усовершенствуем ее. Если вы помните, образец для поиска мы "вмонтировали" глубоко в программу, а это, очевидно, не лучшее решение. Построим нашу программу по аналогии с grep из UNIXa, т. е. так, чтобы образец для поиска задавался первым аргументом в командной строке.
#include ‹stdio.h›
#include ‹string.h›
#define MAXLINE 1000
int getline(char *line, int max);
/* find: печать строк с образцом, заданным 1-м аргументом */
main(int argc, char *argv[])
{
char line[MAXLINE];
int found = 0;
if (argc != 2)
printf("Используйте в find образец\n");
else
while (getline(line, MAXLINE) › 0)
if (strstr(line, argv[1]) ›= NULL) {
printf ("%s", line);
Читать дальше