__argc , __argv , __wargv
Глобальная переменная __argc — это счетчик числа аргументов командной строки, переданных программе. __argv — указатель на массив одно- или многобайтовых строк, который содержит аргументы программы, а __wargv — указатель на массив строк расширенных символов, который содержит аргументы программы. Эти глобальные переменные обеспечивают аргументы для main или wmain .
Синтаксис
extern int __argc; extern char ** __argv; extern wchar_t ** __wargv;
Замечания
В программе, которая использует main функцию, __argc инициализируется __argv при запуске программы с помощью командной строки, которая используется для запуска программы. Командная строка разбирается на отдельные аргументы, а подстановочные знаки разворачиваются. Число аргументов назначается функции __argc , строки аргументов выделяются в куче, а указатель на массив аргументов назначается __argv . В программе, которая скомпилирована для использования расширенных символов и функции wmain , аргументы анализируются и подстановочные знаки разворачиваются как строки расширенных символов, а указатель на массив строк аргументов назначается __wargv .
Для создания переносимого кода рекомендуется использовать аргументы, переданные в main , чтобы получить аргументы командной строки в программе.
Сопоставления подпрограмм универсального текста
| Подпрограмма Tchar.h | _UNICODE не определен | _UNICODE Определенные |
|---|---|---|
| __targv | __argv | __wargv |
Требования
| Глобальная переменная | Обязательный заголовок |
|---|---|
| __argc , __argv , __wargv | , (C++) |
__argc , __argv и __wargv являются расширениями Майкрософт. Дополнительные сведения о совместимости см. в разделе Совместимость.
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. В этом случае не следует подавлять подпрограмму обработки среды, так как она используется для передачи данных о среде из родительского процесса в дочерний.
Для чего в main (int argc, char *argv[])
Недавно начал изучать C++ и не понимаю зачем принимать 2 аргумента? Один — целое число, а второй — массив, ещё и память выделяется как-то странно без new . Откуда приходят эти аргументы и зачем их используют?
Отслеживать
28.8k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков
задан 10 июн 2013 в 19:10
Павел Дурa Павел Дурa
1,421 3 3 золотых знака 21 21 серебряный знак 43 43 бронзовых знака
К уже данным ответам могу только посоветовать для более глубокого понимания почитать man 3 exec и маны из SEE ALSO в нем. Возможно, кроме них представляют интерес man system и man popen . -- Кстати, в общем случае в main передается не 2, а 3 аргумента (3-ий массив адресов переменных окружения (environment), завершающийся нулем. Он аналогичен второму, в котором передаются адреса аргументов командной строки) int main (int ac, char **av, char **env);
10 июн 2013 в 20:09
далеко не факт, что у человека линукс. да и третий параметр - это компиляторозависимое, хотя многие поддерживают это. В принципе, никто ведь не мешал разработчикам сделать что то вида int main(std::vector
10 июн 2013 в 20:23
@KoVadim, не знаю, какие компиляторы как, а g++ в винде замечательно все это поддерживает: c:/Users/avp/src/cc/hashcode $ g++ 3args.cpp c:/Users/avp/src/cc/hashcode $ ./a a1 a2 arg av[0]: c:\Users\avp\src\cc\hashcode\a.exe av[1]: a1 av[2]: a2 env env[0]: ALLUSERSPROFILE=C:\ProgramData env[1]: APPDATA=C:\Users\avp\AppData\Roaming . env[53]: windows_tracing_flags=3 env[54]: windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log c:/Users/avp/src/cc/hashcode $ -- Да и execl("a.exe", "xaxa", 0); тоже работает.
10 июн 2013 в 21:13
да уж, @KoVadim с линуксом явно погорячился ))
11 июн 2013 в 5:27
9 ноя 2022 в 8:11
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
Это параметры командной строки, которые могут быть переданы Вашему приложению. Первый аргумент передается по той причине, что встроенные массивы в С/С++ не хранят размер и передача размера - один из способов об этом узнать (можно к примеру договориться, что последний элемент будет нулевым, но это накладывает определенные ограничения).
память выделяется как-то странно без new
память выделяется в другом месте, а в функцию приходит только указатель. Как именно она там выделяется - в данный момент Вас тревожить не должно. Главное помнить правило - "кто память выделяет, тот обычно ее и удаляет". В данном случае компилятор вставит весь необходимый код, который выделит память и освободит. Хотя там ещё и система немного может выделить.
Как же приходят аргументы?
К примеру, Вы можете запустить программу так
myprog param1 param2 param3
в этом случае argc будет иметь значение 4. argv[1] будет равно param1. argv[3] будет равно param3. Возникает вопрос, а что в нулевом элементе? а там имя программы в том виде, в котором его предоставляет операционная система. То есть, там может быть как myprog, так и имя с полным путем.
- Аргументы функции main(): argv и argc
- Параметры функции main (argc, argv)
upd: для любителей стандарта - читать пункт 3.6.1. Там в частности сказано, что официально есть два варианта - int main() и int main(int argc, char *argv[]) (хотя последний можно записать как int main(int argc, char **argv) - суть не меняется). Все остальное - на усмотрение компиляторов.
Argc argv 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 будет три элемента.