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

Если у меня есть это:

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

В теле иногда можно найти программы, использующие argv[1].

Когда мы используем argv[1] вместо argv[0]? Это только тогда, когда мы просто хотим прочитать второй аргумент в командной строке?


person Simplicity    schedule 07.03.2011    source источник


Ответы (7)


Согласно соглашению, argv[0] — это имя текущей программы (или путь), а argv[1]argv[argc - 1] — это аргументы командной строки, предоставляемые пользователем.

Однако это не обязательно должно быть правдой — программы могут использовать функции, специфичные для ОС, чтобы обойти это требование, и это случается достаточно часто, поэтому вы должны знать об этом. (Я не уверен, что вы можете многое сделать, даже если знаете об этом...)

Пример:

gcc -O3 -o temp.o "My file.c"

будет (должен) привести следующие аргументы:

argc: 5
argv: ["gcc", "-O3", "-o", "temp.o", "My file.c"]

Таким образом, argv[0] будет означать gcc, не -O3.

person user541686    schedule 07.03.2011
comment
Ну, argv[0] не обязательно должен быть реальным путем к исполняемому файлу, но argv[1]..argv[argc - 1] должен быть аргументом командной строки :-). - person Tony Delroy; 07.03.2011
comment
5.1.2.2.1 раздел 2 пункт 4: если значение argc больше нуля, строка, на которую указывает argv[0], представляет имя программы; argv[0][0] должен быть нулевым символом, если имя программы недоступно в хост-среде. Если значение argc больше единицы, строки, на которые указывают символы с argv[1] по argv[argc-1], представляют собой параметры программы. - person Chris Lutz; 07.03.2011
comment
@Chris: Мы надеемся на это, но вы можете легко доказать, что это неверно в Windows в некоторых ситуациях. :\ - person user541686; 07.03.2011
comment
+1, для завершения также по соглашению (то есть, потому что так сказано в стандарте) argv[ argc ] равно '0' (§3.6.1/2 [...] Значение argv[argc] должно быть 0.) - person David Rodríguez - dribeas; 07.03.2011
comment
@Mehrdad - MSVC никогда не претендовала на то, чтобы быть соответствующей реализацией C. @David - Нет, argv[argc] имеет тип char *, а не char, поэтому значение 0 интерпретируется как NULL. - person Chris Lutz; 07.03.2011
comment
@Chris: Да, вот почему мы должны знать об этом. ;) - person user541686; 07.03.2011
comment
@ Крис, ты прав, это то, что происходит, когда я печатаю, не задумываясь :) (я сжульничал и исправил предыдущий комментарий для тех, кто прочитал это постфактум) - person David Rodríguez - dribeas; 07.03.2011
comment
@Mehrdad - Я хочу сказать, что если это в стандарте, это немного больше, чем условность. - person Chris Lutz; 07.03.2011
comment
@Chris: UNIX/Linux, конечно, тоже: все семейство функций exec позволяет исполняющемуся процессу указывать значение argv для своего дочернего элемента — по соглашению это имя исполняемого файла дочернего элемента, но есть хорошо известный хак многолетней давности, чтобы скрыть это. были запущены, например irc и, кажется, работает, скажем, vim: просто запустите крошечную программу, выполняющую первую, а вторую принудительно в argv[0]. Таким образом, простой ps и т. Д. Создаст впечатление, что вы работаете. - person Tony Delroy; 07.03.2011
comment
@Chris: если это есть в стандарте, это немного больше, чем соглашение - все еще вопрос определения ... требование Стандарта выполняется, если имя программы определяется как то, что решает исполняющая функция. Я не вижу в Стандарте каких-либо конкретных условий по этому поводу... знаете ли вы какие-нибудь? - person Tony Delroy; 07.03.2011
comment
@Tony - Если кто-то делает exec, чтобы обмануть программу, заставив ее думать, что ее имя - это что-то другое, то мы должны ожидать, что эта программа будет думать, что ее имя - это то, что мы ей сказали, не так ли? Следовательно, программа должна верить, что ее имя — argv[0], и если мы солгали нашей дочерней программе, нам должно быть стыдно за себя. ;) - person Chris Lutz; 07.03.2011

argv — это массив указателей, и каждый указатель в этом массиве хранит один аргумент из командной строки. Таким образом, argv[0] — это первый аргумент (то есть сам исполняемый файл/программа), argv[1] — второй аргумент и так далее!

Общее количество аргументов определяется argc.

person Nawaz    schedule 07.03.2011
comment
Почему -1: Это точно правильно. argv[1] — второй аргумент в командной строке, интерпретируемый оболочкой. И является первым аргументом, который должно интерпретировать приложение. - person Martin York; 07.03.2011
comment
@Nawaz - Кто-то, вероятно, прыгнул, прежде чем посмотрел. Проголосуйте и успокойтесь, зная, что этот ответ принес вам 28 очков репутации. :) - person Chris Lutz; 07.03.2011
comment
@Nawaz, @Martin: каждый указатель в этом массиве хранит аргумент из командной строки. Я считаю, что это вводит в заблуждение, и что первое значение — имя программы — не следует рассматривать как аргумент командной строки; это просто имя программы. (Это та же самая проблема, которая привела к тому, что 4 человека подвергли сомнению ныне удаленный ответ от Alnitak.) Я не смог найти в Стандарте ничего, поддерживающего любую точку зрения ... любую авторитетную ссылку, и я пересмотрю, но в настоящее время я верю в это неправильно. - person Tony Delroy; 07.03.2011
comment
@Nawaz, @Martin: из-за отсутствия лучшей ссылки я соглашусь с использованием справочной страницы Linux, в которой говорится о массиве указателей ... представляют список аргументов, доступных для новой программы. Первый аргумент, по соглашению, .... Я исправлен, но не могу отменить свой голос против, если ответ не будет отредактирован. Наваз: прости за это! - person Tony Delroy; 07.03.2011
comment
@Tony: Какую часть моего сообщения я должен отредактировать? Кроме того, я не думаю, что это вводит в заблуждение, ЕСЛИ вы прочитали полный пост. - person Nawaz; 07.03.2011
comment
@Tony: Хорошо, я только что сделал один аргумент из командной строки из аргумента из командной строки. - person Nawaz; 07.03.2011
comment
@Nawaz: one vs the или a - незначительное, но стоящее улучшение (сам я не собирался упоминать об этом). В противном случае, на мой взгляд, все еще немного сомнительный бит (даже принимая использование страницы руководства Linux) заключается в том, существует ли различие между вашим аргументом из командной строки и тем, что он является частью списка аргументов. Вы можете заменить командную строку списком аргументов или добавить кавычку, чтобы поддержать идею списка аргументов, включая имя программы, но это ваш выбор.... - person Tony Delroy; 07.03.2011
comment
@Tony: Какое это имеет значение, если вы понимаете, что argv[0] — это сам исполняемый файл? Все, что вы обсуждаете, это терминология, а не концепция или принцип работы программы! - person Nawaz; 07.03.2011
comment
@Nawaz: это важно, потому что мы пытаемся недвусмысленно сообщить, как работает программа, и если у нас нет общепонятной терминологии, то утверждения, которые мы делаем о том, как все работает, могут быть поняты читателями как подразумевающие другие концепции и поведение, чем предназначена. (Если бы вы меньше полагались на терминологию и показывали, как отдельные значения отображаются на содержимое argv[] — как это делают Оскар и Мердад в своих ответах — было бы меньше места для путаницы.) - person Tony Delroy; 07.03.2011
comment
@Tony: Ты прочитал мой пост ПОЛНОСТЬЮ? Особенно строка argv[0] is the first argument (that is the executable/program itself)? - person Nawaz; 07.03.2011
comment
@Nawaz: да, Наваз, и раньше я не соглашался, потому что считал первым аргументом из командной строки (контекст, перенесенный из предыдущего предложения) argv[1]. С тех пор я дал вам преимущество в любых сомнениях, потому что справочная страница linux exec считает, что список аргументов включает имя программы, и я не могу найти более авторитетный источник, указывающий, считается ли имя программы аргументом или нет. В любом случае, я перешел от голосования против к голосованию за вас - чего еще вы хотите...? ;-П - person Tony Delroy; 07.03.2011
comment
@Tony: Все, что я говорю, это то, что на самом деле не имеет значения, как вы это называете. Все дело в том, что вы имеете в виду под тем, что вы называете. Теперь я не буду называть это ни командной строкой, ни списком аргументов, я назову это абракадабра-линейный-список, и под этим я подразумеваю то, что раньше имел в виду командную строку, или то, что вы имеете в виду список аргументов. Надеюсь, теперь ты понял, что я имею в виду :D - person Nawaz; 07.03.2011

Предположим, ваш исполняемый файл C++:

/home/user/program (или C:\program.exe в Windows)

если вы выполните:

./home/user/program 1 2 (или C:\program.exe 1 2 в Windows)

argv[0] = /home/user/program (C:\program.exe)
argv[1] = 1
argv[2] = 2

Это потому, что:

  • argv[0] — путь к исполняемому файлу
  • argv[1] — первый аргумент

Изменить:

Теперь я вижу, что argv[0] не обязательно является путем к исполняемому файлу.
Прочитайте следующий вопрос SO: Гарантировано ли, что args[0] является путем выполнения?

person Oscar Mederos    schedule 07.03.2011
comment
Обратите внимание, что если argc == 1, то argv[1] не существует. argc - это не количество аргументов, это размер argv (на 1 больше, чем количество аргументов). - person Chris Lutz; 07.03.2011
comment
@Cris Lutz: Скорее, если argc == 1, то argv[1] == 0. В §3.6.1/2 прямо указано, что argv[argc] == 0 - person David Rodríguez - dribeas; 07.03.2011
comment
@ Дэвид - на самом деле я этого не знал, пока не нашел ответ Мехрдада. Рад был узнать, что мне это не сойдет с рук. - person Chris Lutz; 07.03.2011

argv[0] — путь выполнения программы, argv[1] — первый параметр программы

person Bogatyr    schedule 07.03.2011

Короткий ответ: да, массив содержит все параметры, переданные в программу.

person Nim    schedule 07.03.2011

поскольку argv[0] — это путь к файлу самой программы. Дополнительные параметры командной строки находятся в дополнительных указателях, argv[1],argv[2].. Вы можете прочитать больше здесь: http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html

person DhruvPathak    schedule 07.03.2011

Да, это в основном так, argv[1] — второй параметр командной строки. Первый параметр командной строки — это имя самой программы.

В качестве альтернативы, чтобы избежать семантического беспорядка, который изначально был в этом ответе, и комментариев от других, может иметь смысл назвать argv[0] параметром zeroth, так что argv[1] теперь будет «первым» введенных пользователем значений.

В любом случае это происходит из семейства функций exec(), например. execl, который имеет использование:

 int execl(const char *path, const char *arg0, ... /*, (char *)0 */);

В оболочке (Unix), когда вы вводите команду, при необходимости оболочка сначала разрешает имя команды (используя $PATH), чтобы найти реальный абсолютный путь. Путь (абсолютный или относительный) предоставляется для path, а команда, первоначально введенная, предоставляется как arg0, и в конечном итоге становится argv[0] в вашей программе.

Затем оставшиеся параметры командной строки заканчиваются как argv[1] и т. д.

person Alnitak    schedule 07.03.2011
comment
Хм? Я не уверен, какое у вас здесь определение аргумента, но, насколько я знаю, это первый аргумент, а не второй... - person user541686; 07.03.2011