Аргументы main. Параметры функции main (argc, argv). Практическое значение передачи данных в программу

Бывает, что данные в программу передаются из командной строки при ее вызове. Такие данные называются аргументами командной строки. Выглядит это так, например:

./a.out test.txt ls -lt /home/peter/

Здесь вызываются программы a.out (из текущего каталога) и ls (из одного каталога, указанного в переменной окружения PATH). Первая программа из командной строки получает одно слово - test.txt, вторая - два: -lt и /home/peter/.

Если программа написана на языке C, то при ее запуске управление сразу передается в функцию main() , следовательно, именно она получает аргументы командной строки, которые присваиваются ее переменным-параметрам.

До этого мы определяли функцию main() так, как-будто она не принимает никакие параметры и ничего не возвращает. На самом деле в языке C любая функция по-умолчанию (если не определено ничего иного) возвращает целое число. В этом можно убедиться. Если записать код таким образом:

main() { printf ("Hi\n " ) ; return 0 ; }

То никакого предупреждения или ошибки при компиляции не возникнет. То же самое будет, если записать int main() . Это доказывает, что функция по-умолчанию возвращает целое число, а не ничто (void). Хотя то, что возвращает функция всегда можно "переопределить", например, voidmain() или float main() .

При вызове программы из командной строки в нее всегда передается пара данных:

  1. целое число , обозначающее количество слов (элементов, разделенных пробелами) в командной строке при вызове,
  2. указатель на массив строк , где каждая строка - это отдельное слово из командной строки.

Следует иметь в виду, что само имя программы также считается. Например, если вызов выглядит так:

./a.out 12 theme 2

То первый аргумент программы имеет значение 4, а массив строк определяется как {"./a.out", "12", "theme", "2"}.

Обратите внимание на терминологию, есть всего два аргумента программы (число и массив), но сколько угодно аргументов командной строки. Аргументы командной строки "преобразуются" в аргументы программы (в аргументы функции main()).
Эти данные (число и указатель) передаются в программу даже тогда, когда она просто вызывается по имени без передачи в нее чего-либо: ./a.out. В таком случае первый аргумент имеет значение 1, а второй указывает на массив, состоящий всего из одной строки {"./a.out"}.

То, что в программу передаются данные, вовсе не означает, что функция main() должна их принимать. Если функция main() определена без параметров, то получить доступ к аргументам командной строки невозможно. Хотя ничего вам не мешает их передавать. Ошибки не возникнет.

Чтобы получить доступ к переданным в программу данным, их необходимо присвоить переменным. Поскольку аргументы сразу передаются в main() , то ее заголовок должен выглядеть таким образом:
main (int n, char *arr)

В первой переменной (n) содержится количество слов, а во второй - указатель на массив строк. Часто второй параметр записывают в виде **arr . Однако это то же самое. Вспомним, что сам массив строк, содержит в качестве своих элементов указатели на строки. А в функцию мы передаем указатель на первый элемент массива. Получается, что передаем указатель на указатель, т.е. **arr .

Задание
Напишите такую программу:

#include int main(int argc, char ** argv) { int i; printf ("%d\n " , argc) ; for (i= 0 ; i < argc; i++ ) puts (argv[ i] ) ; }

Она выводит количество слов в командной строке при ее вызове и каждое слово с новой строки. Вызовите ее без аргументов командной строки и с аргументами.

В программе мы использовали переменные-параметры argc и argv. Принято использовать именно такие имена, но на самом деле они могут быть любыми. Лучше придерживаться этого стандарта, чтобы ваши программы были более понятны не только вам, но и другим программистам.

Практическое значение передачи данных в программу

Если у вас есть опыт работы в командной строке GNU/Linux, вы знаете, что у большинства команд есть ключи и аргументы. Например, при просмотре содержимого каталогов, копировании, перемещении в качестве аргументов указываются объекты файловой системы, над которыми выполняется команда. Особенности ее выполнения определяются с помощью ключей. Например, в команде

Cp -r ../les_1 ../les_101

cp - это имя команды, -r - ключ, а../les_1 и../les_101 - аргументы команды.

Вообще чаще всего в программы при их запуске передаются адреса файлов и "модификаторы" (это ключи) процесса выполнения программы.

Напишем программу, которая открывает указанные пользователем в командной строке файлы на запись или добавление и записывает (добавляет) туда одну и туже информацию, которую пользователь вводит с клавиатуры в процессе выполнения программы:

#include #include main (int argc, char ** argv) { int i, ch; FILE * f[ 5 ] ; if (argc < 3 || argc > 7 ) { puts ("Неверное количество параметров" ) ; return 1 ; } if (strcmp (argv[ 1 ] , "-w" ) != 0 && strcmp (argv[ 1 ] , "-a" ) != 0 ) { puts ("Первый параметр может быть либо -w, либо -a" ) ; return 2 ; } for (i= 0 ; i < argc- 2 ; i++ ) { f[ i] = fopen (argv[ i+ 2 ] , argv[ 1 ] + 1 ) ; if (f[ i] == NULL) { printf ("Файл %s нельзя открыть\n " , argv[ i+ 2 ] ) ; return 3 ; } } while ((ch = getchar () ) != EOF) for (i= 0 ; i < argc- 2 ; i++ ) putc (ch, f[ i] ) ; for (i= 0 ; i < argc- 2 ; i++ ) fclose (f[ i] ) ; return 0 ; }

Пояснения к коду:

  1. Создается массив из пяти файловых указателей. Следовательно можно одновременно открыть не более пяти файлов. Файловый указатель первого файла будет хранится в элементе массива f, второго - в f и т.д.
  2. Проверяется количество аргументов командной строки. Их должно быть не меньше трех, т.к. первый - это имя программы, второй - режим открытия файла, третий - первый или единственный файл, в который будет производится запись. Поскольку программа позволяет открыть только пять файлов, то общее число аргументов командной строки не может быть больше семи. Поэтому если количество аргументов меньше 3 или больше 7, то программа завершается, т.к. оператор return приводит к выходу из функции, даже если после него есть еще код. Возвращаемое из функции значение неравное 0, может быть интерпретировано родительским процессом, как сообщение о том, что программа завершилась с ошибкой.
  3. Проверяется корректность второго аргумента командной строки. Если он не равен ни "-w", ни "-a", то условное выражение во втором if возвращает 1 (true). Функция strcmp() позволяет сравнивать строки и возвращает 0 в случае их равенства.
  4. В цикле for открываются файлы по указанным адресам, которые начинаются с третьего элемента массива argv. Именно поэтому к i прибавляется 2, чтобы получать элементы массива argv, начиная с третьего. Выражение argc-2 указывает на количество переданных имен файлов; т.к. в argc хранится общее число аргументов командной строки, первые два из которых не являются именами файлов.
  5. Выражение argv+1 позволяет "вырезать" из строки "-w" (или "-a") подстроку "w" (или "a"), т.к. argv по сути указатель на первый элемент строки. Прибавляя к указателю единицу, мы смещаем его к следующему элементу массива.
  6. Если файл отрыть не удается, то функция fopen() возвращает NULL. В таком случае программа завершается.
  7. Каждый символ, введенный пользователем с клавиатуры, записывается во все открытые файлы.
  8. В конце файлы закрываются.


В продолжение темы:
Windows

Часть вторая : "Важнейшие характеристики каждого семейства процессоров Intel Core i3/i5/i7. Какие из этих чипов представляют особый интерес" Введение Сначала мы приведём...

Новые статьи
/
Популярные