Int argc, char * argv [] का क्या अर्थ है?


507

कई सी ++ आईडीई और संकलक में, जब यह आपके लिए मुख्य कार्य उत्पन्न करता है, तो यह इस तरह दिखता है:

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

जब मैं बिना IDE के C ++ को कमांड लाइन कंपाइलर के साथ कोड करता हूं, तो मैं टाइप करता हूं:

int main()

बिना किसी पैरामीटर के। इसका क्या मतलब है, और क्या यह मेरे कार्यक्रम के लिए महत्वपूर्ण है?


47
यदि आपका प्रोग्राम कमांड लाइन तर्कों को अनदेखा करने वाला है, तो आप जो लिखते हैं वह ठीक है। यदि आपके प्रोग्राम को कमांड लाइन तर्कों को संसाधित करने की आवश्यकता है, तो आईडीई इसे सही कर रहा है।
जोनाथन लेफ्लर

30
हैकर्स के लिए एक संकेत: int main(int argc, char* argv[], char* envp[])अंतिम तर्क को घोषित करने और मुद्रित करने का प्रयास करें । ;)
ulidtko

7
@ulidtko यह अच्छा नहीं है कि आप उनके कार्यक्रमों में भेद्यता का परिचय देने के लिए नए-नए उपदेश दे रहे हैं;)
गब

13
@ Gab कैसे पर्यावरण चर के साधारण मुद्रण भेद्यता के लिए नेतृत्व? system()उपयोगकर्ता के इनपुट के साथ हमेशा की तरह कॉल, डीबी क्वेश्चन इत्यादि को दागी स्ट्रिंग को पास न करें।
ulidtko

2
@ulidtko दिलचस्प .. क्या आप char **envpतर्क का उपयोग करते समय दागी तार, db प्रश्नों आदि को पास नहीं कर सकते ?
मास्टर जेम्स

जवाबों:


650

argvऔर argcकैसे कमांड लाइन तर्क main()सी और सी ++ में पारित किए जाते हैं ।

argcद्वारा इंगित तार की संख्या होगी argv। यह (व्यवहार में) 1 प्लस तर्कों की संख्या होगी, जैसा कि लगभग सभी कार्यान्वयन कार्यक्रम के नाम को सरणी में प्रस्तुत करेंगे।

कन्वेंशन द्वारा चर argc( लॉजिक काउंट ) और argv( तर्क वेक्टर ) नाम दिए गए हैं, लेकिन उन्हें कोई भी मान्य पहचानकर्ता दिया जा सकता है: int main(int num_args, char** arg_strings)समान रूप से मान्य है।

int main()यदि आप कमांड लाइन तर्कों को संसाधित करने का इरादा नहीं रखते हैं, तो उन्हें पूरी तरह से छोड़ा जा सकता है ।

निम्नलिखित कार्यक्रम का प्रयास करें:

#include <iostream>

int main(int argc, char** argv) {
    std::cout << "Have " << argc << " arguments:" << std::endl;
    for (int i = 0; i < argc; ++i) {
        std::cout << argv[i] << std::endl;
    }
}

इसे ./test a1 b2 c3आउटपुट के साथ चलाना

Have 4 arguments:
./test
a1
b2
c3

8
argc0 हो सकता है, जिस स्थिति में argvNULL हो सकता है। यह मानक AFAIK द्वारा अनुमत है। मैंने ऐसी प्रणाली के बारे में कभी नहीं सुना है जो व्यवहार में ऐसा करती है, लेकिन यह निश्चित रूप से मौजूद हो सकती है और किसी भी मानकों का उल्लंघन नहीं करेगी।
चक

77
@ चक: चूंकि "का मान argv[argc]0 होगा" (C ++ 03 .63.6.1 / 2), argvशून्य नहीं हो सकता।
जेम्स मैक्नेलिस

20
@ चक: सी (कम से कम C99) की समान आवश्यकता है।
जेम्स मैकनेलिस

2
मैंने सोचा कि मुझे जोड़ना चाहिए, यह वहाँ से बाहर अधिकांश प्रणालियों में एक ही है, हालांकि वे कुछ समय के लिए अमूर्त हैं। उदाहरण के लिए, पास्कल / डेल्फी / लाजर में, आपको मिलता है; ParamStr और ParamCount (यदि स्मृति मुझे सही सेवा देती है)। मेरी बात यह है कि जब आप (यदि कभी भी) अन्य भाषाओं / भाषाओं में देशी एप्लिकेशन लिखते हैं, तो एक अच्छा मौका है कि ऊपर आपको उपयोग करने के लिए परिभाषित किया गया है, और, वे सभी प्रणालियों में पूरी तरह से समान (गणना / स्ट्रिंग सूची) काम करते हैं जो समर्थन करते हैं उन्हें।
क्रिश्चियन

8
@ EmilVikström नहीं, यह एक गंभीर त्रुटि है जिसका परिणाम शायद एक सेगफॉल्ट में होता है। *NULLनिश्चित रूप से नहीं के बराबर है NULL
meagar

52

argcकमांड लाइन से आपके प्रोग्राम में तर्कों की संख्या को पार किया जा रहा है और argvयह तर्कों का सार है।

आप उनकी संख्या जानने के तर्कों के माध्यम से लूप कर सकते हैं:

for(int i = 0; i < argc; i++)
{
    // argv[i] is the argument at index i
}

19

मान लीजिए कि आप अपना प्रोग्राम इस प्रकार चलाते हैं ( shसिंटैक्स का उपयोग करके ):

myprog arg1 arg2 'arg 3'

यदि आपने अपना मुख्य घोषित कर दिया है int main(int argc, char *argv[]), तो (अधिकांश वातावरण में), आपके main()को जैसे कहा जाएगा:

p = { "myprog", "arg1", "arg2", "arg 3", NULL };
exit(main(4, p));

हालाँकि, यदि आपने अपना मुख्य घोषित किया है, तो int main()इसे कुछ कहा जाएगा

exit(main());

और आप तर्कों को पारित नहीं करते हैं।

दो अतिरिक्त बातें ध्यान दें:

  1. ये केवल दो मानक-अनिवार्य हस्ताक्षर हैं main। यदि कोई विशेष प्लेटफ़ॉर्म अतिरिक्त तर्क या एक अलग रिटर्न प्रकार को स्वीकार करता है, तो यह एक विस्तार है और इसे पोर्टेबल कार्यक्रम में भरोसा नहीं किया जाना चाहिए।
  2. *argv[]और **argvबिल्कुल समान हैं, इसलिए आप इस int main(int argc, char *argv[])रूप में लिख सकते हैं int main(int argc, char **argv)

2
यदि हम तकनीकी हैं, तो basic.start.main/2स्पष्ट रूप से कार्यान्वयन-परिभाषित अतिरिक्त संस्करणों की अनुमति देता है main(), बशर्ते कि कार्यान्वयन दो पूर्वनिर्धारित संस्करण प्रदान करता है। तो, वे बिल्कुल गैर-अनुरूप नहीं हैं । सबसे आम एक है envp, जो सी और सी ++ दोनों में इतनी अच्छी तरह से जाना जाता है कि यह शाब्दिक रूप से सी मानक के खंड J.5 (सामान्य एक्सटेंशन) में पहली प्रविष्टि है
जस्टिन टाइम -

1
अच्छा पेडेंट्री @ जस्टिन के लिए धन्यवाद। उत्तर को और अधिक सही होने के लिए अद्यतन किया गया।
टोबे स्पाइट

कोई विचार नहीं - मेरा सुझाव है कि आप एक न्यूनतम प्रतिलिपि प्रस्तुत करने योग्य उदाहरण बनाएं और इसे पूछें (यह मानते हुए कि प्रक्रिया आपको स्वयं इसका उत्तर देने में मदद करने के लिए पर्याप्त नहीं है)।
टोबी स्पाईट

9

mainप्रोग्राम शुरू होने पर कमांड लाइन के मापदंडों को प्रस्तुत करने के लिए पैरामीटर। argcपैरामीटर कमांड लाइन तर्क की संख्या का प्रतिनिधित्व करता है, और char *argv[]तार (चरित्र संकेत) अलग-अलग कमांड लाइन पर प्रदान किए गए तर्कों का प्रतिनिधित्व करने की एक सरणी है।


2
Argv [] हमेशा argv [arg] एक अशक्त सूचक के रूप में होता है। और अर्गव [0] हमेशा (पूर्ण पथ) / निष्पादन योग्य होता है, एक
शून्य

3
@ user3629249: जरूरी नहीं; argv[0]प्रोग्राम को लॉन्च करने वाले कार्यक्रम को जो कुछ भी दिया गया है, वह इस प्रकार है argv[0]। बैश के मामले में, यह अक्सर (शायद हमेशा) निष्पादन योग्य का मार्गनाम होता है, लेकिन बैश एकमात्र प्रोग्राम नहीं है जो अन्य कार्यक्रमों को निष्पादित करता है। यह अनुमेय है, हालांकि सनकी, उपयोग करने के लिए char *args[] = { "cat", "/dev/null", "/etc/passwd", 0 }; execv("/bin/ls", args);:। कई सिस्टम पर, इस कार्यक्रम के द्वारा देखा मूल्य के रूप में argv[0]किया जाएगा cat, भले ही निष्पादन योग्य है /bin/ls
जोनाथन लेफ़लर

6

mainसमारोह दो पैरामीटर है, कर सकते हैं argcऔर argvargcएक पूर्णांक ( int) पैरामीटर है, और यह प्रोग्राम में दिए गए तर्कों की संख्या है।

कार्यक्रम का नाम हमेशा पहला तर्क होता है, इसलिए किसी कार्यक्रम में कम से कम एक तर्क argcहोगा और न्यूनतम मान एक होगा। लेकिन अगर किसी कार्यक्रम के दो तर्क हैं तो argcवसीयत का मूल्य तीन होगा।

पैरामीटर argvएक स्ट्रिंग सरणी को इंगित करता है और इसे तर्क वेक्टर कहा जाता है । यह फ़ंक्शन तर्कों का एक आयामी स्ट्रिंग सरणी है।


5
int main();

यह एक साधारण घोषणा है। यह कोई कमांड लाइन तर्क नहीं ले सकता है।

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

इस घोषणा का उपयोग तब किया जाता है जब आपके प्रोग्राम को कमांड-लाइन तर्क लेना चाहिए। इस तरह से चलाने पर:

myprogram arg1 arg2 arg3

argc, या तर्क गणना, 4 (चार तर्क) पर सेट किया जाएगा, और argv, या तर्क क्षेत्र, "मायप्रोग्राम", "arg1", "arg2", और "arg3" को स्ट्रिंग पॉइंटर्स के साथ आबाद किया जाएगा। कार्यक्रम आह्वान ( myprogram) तर्कों में शामिल है!

वैकल्पिक रूप से, आप उपयोग कर सकते हैं:

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

यह भी मान्य है।

एक और पैरामीटर है जिसे आप जोड़ सकते हैं:

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

envpपैरामीटर भी वातावरण चर शामिल हैं। प्रत्येक प्रविष्टि इस प्रारूप का अनुसरण करती है:

VARIABLENAME=VariableValue

इस तरह:

SHELL=/bin/bash    

पर्यावरण चर सूची शून्य-समाप्त है।

महत्वपूर्ण: कॉल में सीधे किसी भी argvया envpमूल्यों का उपयोग न करें system()! यह एक विशाल सुरक्षा छिद्र है क्योंकि दुर्भावनापूर्ण उपयोगकर्ता कमांड-लाइन कमांड के लिए पर्यावरण चर निर्धारित कर सकते हैं और (संभावित) बड़े पैमाने पर क्षति का कारण बन सकते हैं। सामान्य तौर पर, बस उपयोग नहीं करते हैं system()। C पुस्तकालयों के माध्यम से कार्यान्वित लगभग एक बेहतर समाधान है।


3

पहला पैरामीटर प्रदान किए गए तर्कों की संख्या है और दूसरा पैरामीटर उन तर्कों का प्रतिनिधित्व करने वाले तार की एक सूची है।


7
argv में पहली प्रविष्टि [0] प्रोग्राम का नाम है, न कि एक तर्क
user3629249

@ user3629249 प्रोग्राम का नाम प्रोग्राम पथ के साथ। ;)
मास्टर जेम्स

1

दोनों

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

C या C ++ प्रोग्राम के लिए प्रवेश बिंदु की कानूनी परिभाषा है। स्ट्रॉस्ट्रुप: सी ++ स्टाइल और टेक्नीक एफएक्यू में कुछ बदलावों का विवरण दिया गया है जो आपके मुख्य कार्य के लिए संभव या कानूनी हैं।


4
संगतता और पठनीयता के लिए ... int main()==> int main(void)... में शून्य डालना चाह सकते हैं । मुझे नहीं पता कि क्या सी के सभी पुराने संस्करण शून्य कार्यों को घोषणा में एक खाली पैरामीटर सूची रखने की अनुमति देते हैं।
dylnmc

1
@dylnmc यह किसी भी पठनीयता का लाभ नहीं देता है, और सभी C ++ संस्करणों में बिल्कुल समान है। केवल C में इसका अंतर होता है, लेकिन केवल घोषणाओं में, परिभाषा में नहीं।
रुस्लान

@Ruslan क्षमा करें, मैंने इसे तब पोस्ट किया था जब मैं सिर्फ C सीख रहा था, और मैंने पढ़ा होगा कि C के बहुत शुरुआती संस्करणों में voidयह आवश्यक है। उस पर मुझे उद्धृत न करें, और मैं अब जानता हूं कि यह थोड़ी मूर्खतापूर्ण टिप्पणी है। यह चोट नहीं कर सकता है, हालांकि।
dylnmc

क्या होगा अगर argc <3 में कोई त्रुटि है? क्या गलत हो सकता है?
AVI
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.