Как передать аргументы в main c
Перейти к содержимому

Как передать аргументы в main c

  • автор:

Как передать аргументы в main c

В прошлых темах функция main определялась без параметров. Однако также можно определить данную функцию с параметрами:

int main(int argc, char* argv[]) < // инструкции >

Первый параметр, argc , представляет тип int и хранит количество аргументов командной строки. Второй параметр, argv[] , представляет собой массив указателей и хранит все переданные аргументы командной строки в виде строк. Таким образом, благодаря данным параметрам мы можем при вызове программы в консоли передать ей некоторые данные.

Например, определим следующую программу:

#include int main(int argc, char* argv[]) < // выводим все переданные аргументы в цикле for (int i <>; i < argc; ++i) < std::cout >

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

c:\cpp>g++ hello.cpp -o hello & hello hello

В моем случае код программы расположен в файле «hello.cpp» и компилируется в файл с именем hello. После запуска программы, даже если мы не передаем ей никакх аргументов, в массиве argv[] будет как минимум один элемент — название файла программы. То есть в моем случае в массиве будет одна строка «hello». А первый параметр, argc , будет равен 1.

Передадим программе какие-нибудь аргументы

c:\cpp>g++ hello.cpp -o hello & hello Tom 38 hello Tom 38

Здесь программе при запуске передается два значения — «Tom» и «38». Передаваемые аргументы разделяются пробелом. Причем даже если передается число (как в случае с вторым аргументом), то программа все равно получает его в виде строки. Соответственно теперь в массиве argv будет три элемента.

Передача аргументов в программу. Параметры функции main языка C

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

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

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

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

До этого мы определяли функцию main так, как-будто она не принимает никакие аргументы, далее будет показано, как определить заголовок функции иначе.

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

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

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

./a.out 12 theme 2

, то первый аргумент программы имеет значение 4, а массив строк определяется как .

Обратите внимание на терминологию, есть всего два аргумента программы (число и массив), но сколько угодно аргументов командной строки. Аргументы командной строки «преобразуются» в аргументы программы (в аргументы функции main() ).

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

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

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

int main(int n, char *arr[])

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

Программа ниже выводит количество слов в командной строке при вызове, а также каждое слово с новой строки.

#include int main(int argc, char **argv) { printf("%d\n", argc); for (int i = 0; i  argc; i++) puts(argv[i]); }
pl@desk:~$ ./a.out 1 ./a.out pl@desk:~$ ./a.out -u 120 "hello" 4 ./a.out -u 120 hello

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

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

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

cp -r ../les_1 ../les_101

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

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

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

#include #include int main(int argc, char **argv)  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[0] , второго — в f[1] и т.д.
  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]+1 позволяет «вырезать» из строки «-w» (или «-a») подстроку «w» (или «a»), т. к. argv[1] по сути указатель на первый элемент строки. Прибавляя к указателю единицу, мы смещаем его к следующему элементу массива.
  6. Если файл отрыть не удается, то функция fopen() возвращает NULL . В таком случае программа завершается.
  7. Каждый символ, введенный пользователем с клавиатуры, записывается во все открытые файлы.
  8. В конце файлы закрываются.

Курс с решением задач:
pdf-версия

Аргументы функции MAIN()

Borland С++ поддерживает три аргумента main(). Первые два — это традиционные argc и argv. Это единственные аргументы функции main(), определяемые стандартом ANSI С. Они позволяют передавать аргументы командной строки в программу. Аргументы командной строки — это информация, следующая за именем программы в командной строке операционной системы. Например, когда программа компилируется с помощью строчного компилятора Borland, набирается, как правило, bcc имя_ программы

где имя_программы — это программа, которую необходимо откомпилировать. Имя программы передается компилятору в качестве аргумента.

Параметр argc содержит число аргументов командной строки и является целым числом. Он всегда равен, по крайней мере, 1, поскольку имя программы квалифицируется как первый аргумент. Параметр argv — это указатель на массив символьных указателей. Каждый элемент данного массива указывает на аргумент командной строки. Все аргументы командной строки — это строки. Все числа конвертируются программой во внутренний формат. Следующая программа выводит «Hello», а затем имя пользователя, если его набрать прямо за именем программы:

#include
int main(int argc, char *argv[])
if(argc!=2)
printf («You forgot to type your name\n»);
return 1;
>
printf(«Hello %s», argv[1]);
return 0;
>

Если назвать данную программу name, а имя пользователя Сергей, то для запуска программы следует набрать:
name Сергей.
В результате работы программы появится:
«Hello Сергей».

Аргументы командной строки должны отделяться пробелами или табуляциями. Запятые, точки с запятыми и им подобные символы не рассматриваются как разделители. Например:

состоит из трех строк, в то время как

это одна строка — запятые не являются разделителями.

Если необходимо передать строку, содержащую пробелы или табуляции в виде одного аргумента, следует ее заключить в двойные кавычки. Например, это один аргумент:

Важно правильно объявить argv. Наиболее типичным методом является:

Пустые скобки указывают на то, что массив не имеет фиксированной длины. Можно получить доступ к отдельным элементам с помощью индексации argv. Например, argv[0] указывает на первую строку, всегда содержащую имя программы. argv[1] указывает на следующую строку и так далее.

Ниже приведен небольшой пример по использованию аргументов командной строки. Он отсчитывает в обратном порядке от значения, указанного в командной строке, и при достижении нуля подает сигнал. Обратим внимание, что первый аргумент содержит число, преобразованное в целое число с использованием стандартной функции atoi(). Если в качестве второго аргумента присутствует строка «display», то на экране будет отображаться сам счетчик.

#include
#include
# include
int main(int argc,, char *argv[])
int disp, count;
if(argc <2)
printf(«You must enter the length of the count\n»);
printf («on the command line. Try again.\n»);
return 1;
>
if (argc==3 && !strcmp(argv[2],»display»)) disp = 1;
else disp = 0;
for(count=atoi(argv[1]); count; -count)
if (disp) printf(«%d «, count);
printf(«%c», ‘\a’); /* на большинстве компьютеров это звонок */
return 0;
>

Обратим внимание, что если не указаны аргументы, появляется сообщение об ошибке. Это наиболее типично для программ, использующих аргументы командной строки для выдачи инструкций, если была попытка запустить программу без правильной информации.

Для доступа к отдельным символам командной строки следует добавить второй индекс к argv. Например, следующая программа выводит все аргументы, с которыми она вызывалась, по одному символу за раз:

Надо помнить, что первый индекс предназначен для доступа к строке, а второй — для доступа к символу строки.

Обычно argc и argv используются для получения исходных команд. Теоретически можно иметь до 32767 аргументов, но большинство операционных систем не позволяют даже близко подойти к этому. Обычно данные аргументы используются для указания имени файла или опций. Использование аргументов командной строки придает программе профессиональный вид и допускает использование программы в командных файлах.

Если подсоединить файл WILDARGS.OBJ, поставляемый с Borland С++, то можно будет использовать шаблоны в аргументах типа *.EXE. (Borland С++ автоматически обрабатывает шаблоны и соответствующим образом увеличивает argc.) Например, если подсоединить к следующей программе WILDARGS.OBJ, она выдаст, сколько файлов соответствует имени указанного в командной строке файла:

/* Скомпонуйте данную программу с WILDARGS.OBJ */

#include
int main(int argc, char *argv[])
register int i;
printf(«%d files match specified name\n», argc-1);
printf(«They are: «);
for(i=1; i printf («%s «, argv[i]);
return 0;
>

Если назвать данную программу WA, затем запустить ее как указано ниже, получим число файлов, имеющих расширение ЕХE, и список имен этих файлов:

Помимо argc и argv Borland С++ также предоставляет третий аргумент командной строки -env. Параметр env позволяет программе получить доступ к информации о среде операционной системы. Параметр env должен следовать за argc и argv и объявляется следующим образом:

Как можно видеть, env объявляется так же, как и argv. Так же, как и argv, это указатель на массив строк. Каждая строка — это строка среды, определенная операционной системой. Параметр env не имеет аналога параметра argc, который сообщал бы, сколько имеется строк среды. Вместо этого последняя строка среды нулевая. Следующая программа выводит все строки среды, определенные на текущий момент в операционной системе:

/* данная программа выводит все строки окружения */

#include
int main(int argc, char *argv[], char *env[])
int t;
for(t=0; env[t]/ t++)
printf(«%s\n», env[t]);
return 0;
>

Обратим внимание, что хотя argc и argv не используются программой, они должны присутствовать в списке параметров. С не знает имена параметров. Вместо этого их использование определяется по порядку объявления параметров. Фактически можно обозвать параметр как угодно. Поскольку argc, argv и env — это традиционные имена, то лучше их использовать и далее, чтобы любой человек, читающий программу, мог мгновенно понять, что это аргументы функции main().

Для программ типичной задачей является поиск значения, определенного в строке среды. Например, содержимое строки PATH позволяет программам использовать пути поиска. Следующая программа демонстрирует, как найти строки, объявляющие стандартные пути поиска. Она использует стандартную библиотечную функцию strstr(), имеющую следующий прототип:

char *strstr(const char *str1, const char *str2);

Функция strstr() ищет строку, на которую указывает str1 в строке, на которую указывает str2. Если такая строка найдена, то возвращается указатель на первое положение. Если не найдено соответствий, то функция возвращает NULL.

/* программа ищет среди строк окружения строку, содержащую PATH */

#include
#include
int main (int argc, char *argv[], char *env[])
int t;
for(t=0; env[t]; t++)
if(strstr(env[t], «PATH»))
printf(«%s\n», env[t]);
>
return 0;
>

main аргументы функции и командной строки

Все программы C++ должны иметь функцию main . При попытке скомпилировать программу C++ без main функции компилятор вызывает ошибку. (Библиотеки и static библиотеки динамической main компоновки не имеют функции.) Функция main заключается в том, где начинается выполнение исходного кода, но перед вводом main программы в функцию все static члены класса без явных инициализаторов заданы равным нулю. В Microsoft C++глобальные static объекты также инициализированы перед записью main . Несколько ограничений main применяются к функции, которая не применяется к другим функциям C++. Функция main :

  • Невозможно перегружать (см . перегрузку функции).
  • Невозможно объявить как inline .
  • Невозможно объявить как static .
  • Не удается принять свой адрес.
  • Не удается вызвать из программы.

Сигнатура main функции

Функция main не имеет объявления, так как она встроена в язык. Если это сделать, синтаксис main объявления будет выглядеть следующим образом:

int main(); int main(int argc, char *argv[]); 

Если возвращаемое значение не указано, main компилятор предоставляет возвращаемое значение нуля.

Стандартные аргументы командной строки

Аргументы для main обеспечения удобного анализа аргументов командной строки. Типы для параметров argc и argv определяются языком. Имена argc и argv являются традиционными, но вы можете назвать их независимо от того, что вы хотите.

Используются следующие определения аргументов.

argc
Целое число, содержащее количество аргументов, которые следуют в argv. Параметр argc всегда больше или равен 1.

argv
Массив завершающихся null строк, представляющих введенные пользователем программы аргументы командной строки. По соглашению — это команда, argv[0] с помощью которой вызывается программа. argv[1] — первый аргумент командной строки. Последний аргумент из командной строки имеет argv[argc — 1] argv[argc] значение NULL.

Сведения о том, как отключить обработку командной строки, см. в разделе «Настройка обработки командной строки C++».

По соглашению argv[0] — это имя файла программы. Однако в Windows можно создать процесс с помощью CreateProcess . Если вы используете оба первых и второго аргумента ( lpApplicationName и lpCommandLine ), argv[0] может не быть исполняемым именем. Можно использовать GetModuleFileName для получения исполняемого имени и полного пути.

Расширения, относящиеся к Корпорации Майкрософт

В следующих разделах описано поведение майкрософт.

wmain Функция и _tmain макрос

Если вы разрабатываете исходный код для использования широких charактеров Юникода, вы можете использовать точку входа, определенную wmain корпорацией Майкрософт, которая является широкойchar версией main . Ниже приведен синтаксис эффективного объявления для wmain :

int wmain(); int wmain(int argc, wchar_t *argv[]); 

Вы также можете использовать определенный корпорацией Майкрософт _tmain макрос препроцессора, определенный в tchar.h . _tmain разрешает, main если _UNICODE не определено. В противном случае функция _tmain разрешается в функцию wmain . Макросы _tmain и другие макросы, которые начинаются с _t , полезны для кода, который должен создавать отдельные версии для узких и широких charнаборов актировщиков. Дополнительные сведения см. в разделе «Использование универсальных текстовых сопоставлений».

void Возврат изmain

Как расширение Майкрософт, main wmain функции могут быть объявлены как возвращаемые void (без возвращаемого значения). Это расширение также доступно в некоторых других компиляторах, но его использование не рекомендуется. Он доступен для симметрии, если main не возвращает значение.

При объявлении main или возврате void кода в родительский процесс или wmain операционную систему невозможно вернуть exit с помощью инструкции return . Чтобы вернуть exit код, когда main или wmain как void объявлен, необходимо использовать функцию exit .

envp Аргумент командной строки

wmain Сигнатуры main позволяют дополнительному расширению майкрософт для доступа к переменным среды. Это расширение также распространено в других компиляторах для систем Windows и UNIX. Имя envp традиционное, но можно присвоить параметру среды любое имя. Ниже приведены действующие объявления для списков аргументов, включающих параметр среды:

int main(int argc, char* argv[], char* envp[]); int wmain(int argc, wchar_t* argv[], wchar_t* envp[]); 

envp
Необязательный envp параметр — это массив строк, представляющий переменные, заданные в среде пользователя. Этот массив завершается записью NULL. Его можно объявить как массив указателей char на ( char *envp[] ) или как указатель на указатели char на ( char **envp ). Если программа использует wmain вместо main этого, используйте wchar_t вместо него тип char данных.

Блок среды, переданный main и wmain является «замороженным» копией текущей среды. Если вы позже измените среду, выполнив вызов putenv или _wputenv , текущая среда (возвращаемая getenv или _environ _wgetenv _wenviron переменная) изменится, но блок, на который указывает, envp не изменится. Дополнительные сведения о подавлении обработки среды см. в разделе «Настройка обработки командной строки C++». Аргумент envp совместим со стандартом C89, но не со стандартами C++.

Примеры аргументов main

В следующем примере показано, как использовать argc аргументы и envp argv аргументы main для:

// argument_definitions.cpp // compile with: /EHsc #include #include using namespace std; int main( int argc, char *argv[], char *envp[] ) < bool numberLines = false; // Default is no line numbers. // If /n is passed to the .exe, display numbered listing // of environment variables. if ( (argc == 2) && _stricmp( argv[1], "/n" ) == 0 ) numberLines = true; // Walk through list of strings until a NULL is encountered. for ( int i = 0; envp[i] != NULL; ++i ) < if ( numberLines ) cout > 

Анализ аргументов командной строки C++

Правила синтаксического анализа командной строки, используемые кодом Microsoft C/C++, относятся к корпорации Майкрософт. Код запуска среды выполнения использует эти правила при интерпретации аргументов, заданных в командной строке операционной системы:

  • Аргументы разделяются пробелами (пробел или табуляция).
  • Первый аргумент ( argv[0] ) обрабатывается особым образом. Он представляет имя программы. Это должен быть допустимый путь, поэтому разрешены части, заключенные в двойные кавычки ( « ). Эти знаки двойных кавычек не включаются в выходные данные argv[0] . Части, окруженные двойными кавычками, предотвращают интерпретацию пробела или действия табуляции charв качестве конца аргумента. Последующие правила в этом списке не применяются.
  • Строка, окруженная двойными кавычками, интерпретируется как один аргумент, который может содержать актировщики пробелов char. Строку в кавычках можно встроить в аргумент. Курсор ( ^ ) не распознается как экранный charактер или разделитель. Внутри заключенной в кавычки строки пара двойных кавычек интерпретируется как одна экранированная двойная кавычка. Если командная строка заканчивается до того, как будет найдена закрывающая двойная кавычка, все charвыступающие, прочитанные до сих пор, будут выводиться в качестве последнего аргумента.
  • Символ двойной кавычки после обратной косой черты ( ) интерпретируется как литеральный символ двойной кавычки ( « ).
  • Символы обратной косой черты считаются литералами, если сразу за ними не стоит двойная кавычка.
  • Если двойная кавычка стоит после четного числа символов обратной косой черты, в массив argv помещается по одному символу обратной косой черты ( \ ) для каждой пары символов обратной косой черты ( \\ ), а сама двойная кавычка ( « ) интерпретируется как разделитель строк.
  • Если двойная кавычка стоит после нечетного числа символов обратной косой черты, в массив argv помещается по одному символу обратной косой черты ( \ ) для каждой пары символов обратной косой черты ( \\ ). Двойная кавычка интерпретируется как escape-последовательность повторнойmainобратной косой черты, что приводит к тому, что двойный кавычки литералов ( « ) помещается в argv .

Пример синтаксического анализа аргументов командной строки

В следующем примере программы показана передача аргументов командной строки:

// command_line_arguments.cpp // compile with: /EHsc #include using namespace std; int main( int argc, // Number of strings in array argv char *argv[], // Array of command-line argument strings char *envp[] ) // Array of environment variable strings < int count; // Display each command-line argument. cout

Результаты анализа командных строк

В следующей таблице показаны примеры входных данных и ожидаемые выходные данные, иллюстрирующие применение правил из приведенного выше списка.

Входные данные в командной строке argv[1] argv[2] argv[3]
"abc" d e abc d e
a\\b d"e f"g h a\\b de fg h
a\\\"b c d a\"b c d
a\\\\"b c" d e a\\b c d e
a"b"" c d ab" c d

Развертывание подстановочных знаков

Компилятор Майкрософт при необходимости позволяет использовать дикие картаchar актеры, вопросительный знак () и звездочку ( ? * ), чтобы указать имя файла и аргументы пути в командной строке.

Аргументы командной строки обрабатываются внутренней подпрограммой в коде запуска среды выполнения, который по умолчанию не расширяет дикие элементы карта в отдельные строки в массиве argv строк. Вы можете включить расширение wild карта, включив setargv.obj файл ( wsetargv.obj файл для wmain ) в /link параметры компилятора или LINK в командной строке.

Дополнительные сведения о параметрах компоновщика для запуска среды выполнения см. в статье Параметры ссылок.

Настройка обработки командной строки C++

Если программа не принимает аргументы командной строки, можно сохранить небольшой объем пространства, подавив подпрограмму обработки командной строки. Для этого включите файл noarg.obj (для main и wmain ) в параметры компилятора /link или командную строку LINK .

Аналогичным образом, если вы никогда не использовали таблицу среды для доступа к аргументу envp , можно подавить внутреннюю подпрограмму обработки среды. Для этого включите файл noenv.obj (для main и wmain ) в параметры компилятора /link или командную строку LINK .

Программа может вызывать семейство подпрограмм spawn или exec в библиотеке среды выполнения C. В этом случае не следует подавлять подпрограмму обработки среды, так как она используется для передачи данных о среде из родительского процесса в дочерний.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *