চার্জ * আরগভি [] এর অর্থ কি?


507

অনেকগুলি সি ++ আইডিই এবং সংকলকগুলিতে, যখন এটি আপনার জন্য প্রধান ফাংশন উত্পন্ন করে, এটিকে দেখে মনে হয়:

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

আমি যখন আইডিই ছাড়াই সি ++ কোড করি, কেবল একটি কমান্ড লাইন সংকলক দিয়ে আমি টাইপ করি:

int main()

কোনও পরামিতি ছাড়াই। এর অর্থ কী, এবং এটি আমার প্রোগ্রামের পক্ষে অতীব গুরুত্বপূর্ণ?


47
যদি আপনার প্রোগ্রামটি কমান্ড লাইন যুক্তি উপেক্ষা করে চলেছে, তবে আপনি যা লিখবেন তা ঠিক আছে। যদি আপনার প্রোগ্রামটির কমান্ড লাইন আর্গুমেন্টগুলি প্রক্রিয়া করা প্রয়োজন হয়, তবে আইডিই এটি সঠিকভাবে করছে।
জোনাথন লেফলার

30
হ্যাকারদের জন্য একটি ইঙ্গিত: int main(int argc, char* argv[], char* envp[])শেষ আর্গুমেন্ট ঘোষণা এবং মুদ্রণের চেষ্টা করুন । ;)
ulidtko

7
@ জুলিদকো ভাল নয় যে আপনি নতুনদের তাদের প্রোগ্রামগুলিতে দুর্বলতার পরিচয় দিতে শেখাচ্ছেন;)
গ্যাব 是

13
@ গ্যাব কীভাবে পরিবেশের পরিবর্তনশীলগুলির সহজ মুদ্রণ দুর্বলতার দিকে নিয়ে যায়? system()ব্যবহারকারীর ইনপুট সহ যথারীতি কল, ডিবি কোয়েরি ইত্যাদিতে কলঙ্কযুক্ত স্ট্রিং ভার্ব্যাটিম পাস করবেন না ।
ulidtko

2
@ জুলিদকো আকর্ষণীয় .. আপনি কী ব্যাখ্যা করতে পারেন যে char **envpআর্গুমেন্ট ব্যবহারের সময় আপনাকে কেন কলঙ্কযুক্ত স্ট্রিং, ডিবি কোয়েরিগুলি পাস করতে হবে না ?
মাস্টার জেমস

উত্তর:


650

argvএবং argcকীভাবে main()সি এবং সি ++ এ কমান্ড লাইন আর্গুমেন্টগুলি দেওয়া হয় ।

argcদ্বারা নির্দেশিত স্ট্রিংয়ের সংখ্যা হবে argv। এটি (অনুশীলনে) আর্গুমেন্টের সংখ্যা 1 হবে এবং কার্যত সমস্ত বাস্তবায়ন প্রোগ্রামটির নাম অ্যারেতে প্রিপেন্ড করবে।

ভেরিয়েবলগুলির নাম argc( আর্গুমেন্ট গণনা ) এবং argv( আর্গুমেন্ট ভেক্টর ) কনভেনশন অনুসারে দেওয়া হয়েছে তবে তাদের যে কোনও বৈধ শনাক্তকারী দেওয়া যেতে পারে: int main(int num_args, char** arg_strings)সমানভাবে বৈধ।

int main()আপনি যদি কমান্ড লাইন আর্গুমেন্টগুলি প্রসেস করতে না চান তবে এগুলি পুরোপুরি বাদ দেওয়া যায় yield

নিম্নলিখিত প্রোগ্রাম চেষ্টা করুন:

#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 argvহতে পারে, এক্ষেত্রে NULL হতে পারে। এটি স্ট্যান্ডার্ড এএফআইএইসি দ্বারা অনুমোদিত। আমি কখনও এমন কোনও সিস্টেমের কথা শুনিনি যা এটি বাস্তবে এটি করে তবে এটি অবশ্যই উপস্থিত থাকতে পারে এবং কোনও মানদণ্ড লঙ্ঘন করবে না।
চক

77
@ চক: যেহেতু "মানটির মান argv[argc]0 হবে" (সি ++ ০৩ §৩..6.১ / ২), argvনকল হতে পারে না।
জেমস ম্যাকনেলিস

20
@ চক: সি (কমপক্ষে সি 99) এর একই প্রয়োজনীয়তা রয়েছে।
জেমস ম্যাকনেলিস

2
ভেবেছিলাম আমার যুক্ত করা উচিত, বেশিরভাগ সিস্টেমে এটি একই রকম, যদিও তারা কিছু সময় বিমূর্ত থাকে। উদাহরণস্বরূপ, পাসকাল / ডেল্ফি / লাজারাসে, আপনি পান; প্যারামএসটিআর এবং প্যারামাউন্ট (যদি স্মৃতি আমাকে সঠিকভাবে পরিবেশন করে)। আমার বক্তব্যটি হ'ল আপনি যখন অন্য ভাষা / মরদেহে স্থানীয় অ্যাপ্লিকেশন লিখেন, আপনার ব্যবহারের জন্য উপরেরটি সংজ্ঞায়িত করার ভাল সুযোগ রয়েছে এবং সমস্ত সিস্টেমে তারা পুরোপুরি একই (কাউন্ট / স্ট্রিং তালিকা) কাজ করে যা সমর্থন করে তাদের।
খ্রিস্টান

8
@ এমিলভিক্রাস্টম না, এটি একটি মারাত্মক ত্রুটি যা সম্ভবত একটি সেগফোল্টের ফলস্বরূপ। *NULLঅবশ্যই এর সমান নয় NULL
মেগার

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, যা সি এবং সি উভয় ক্ষেত্রেই এতটাই সুপরিচিত যে এটি সি স্ট্যান্ডার্ডের বিভাগ জে 5 (সাধারণ সম্প্রসারণ) এ আক্ষরিক অর্থেই প্রথম প্রবেশ
জাস্টিন সময় - মনিকা

1
জাস্টিন সুন্দর পেডেন্ট্রি জন্য ধন্যবাদ। উত্তরটি আরও সঠিক হতে আপডেট হয়েছে।
টবি স্পিড

কোনও ধারণা নেই - আমি আপনাকে একটি ন্যূনতম প্রজননযোগ্য উদাহরণ তৈরি করার পরামর্শ দিচ্ছি এবং এটি জিজ্ঞাসা করুন (ধরে নিবেন যে প্রক্রিয়াটি আপনার নিজের উত্তর দিতে সহায়তা করার জন্য যথেষ্ট নয়)।
টবি স্পিড

9

প্যারামিটার mainপ্রোগ্রাম যখন এটি শুরু হয়েছিল প্রদান করা কমান্ড লাইন প্যারামিটার প্রতিনিধিত্ব করে। argcপরামিতি কমান্ড লাইন আর্গুমেন্ট সংখ্যা প্রতিনিধিত্ব করে আর char *argv[]স্ট্রিং (চরিত্র পয়েন্টার) পৃথক কমান্ড লাইন প্রদত্ত যুক্তিগুলির প্রতিনিধিত্ব একটি অ্যারে।


2
আরগভি [] এর সর্বদা নাল পয়েন্টার হিসাবে আরগভ [আরগ] থাকে। আর আরগভি [0] হ'ল সর্বদা (সম্পূর্ণ পাথ) / এক্সিকিউটেবল নাম হিসাবে নুল টার্মিনেটেড স্ট্রিং
ব্যবহারকারী 362929249

3
@ ব্যবহারকারী 362929249: অগত্যা নয়; argv[0]প্রোগ্রামটি যা চালু করেছিল তা সি প্রোগ্রামটি হিসাবে দিয়েছিল argv[0]। বাশের ক্ষেত্রে এটি প্রায়শই (সম্ভবত সর্বদা) সম্পাদনযোগ্যের পথের নাম, তবে বাশ একমাত্র প্রোগ্রাম নয় যা অন্যান্য প্রোগ্রামগুলি কার্যকর করে। এটা তোলে permissisble, যদিও অদ্ভুতস্বভাব, ব্যবহার করার জন্য: 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, বা আর্গুমেন্ট ভেক্টরগুলি স্ট্রিং পয়েন্টারগুলি "মাইপ্রোগ্রাম", "আরজি 1", "আরজি 2", এবং "আরগ 3" তে পপুলেট হবে। প্রোগ্রামের আবেদন ( myprogram) আর্গুমেন্টের অন্তর্ভুক্ত!

বিকল্পভাবে, আপনি ব্যবহার করতে পারেন:

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

এটিও বৈধ।

আপনি যুক্ত করতে পারেন এমন আরও একটি প্যারামিটার রয়েছে:

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

envpপরামিতি এছাড়াও বিভিন্ন পরিবেশের রয়েছে। প্রতিটি এন্ট্রি এই বিন্যাস অনুসরণ করে:

VARIABLENAME=VariableValue

এটার মত:

SHELL=/bin/bash    

পরিবেশের ভেরিয়েবলের তালিকাটি নাল-সমাপ্ত termin

গুরুত্বপূর্ণ: সরাসরি কলগুলিতে কোনও argvবা envpমান ব্যবহার করবেন না system()! এটি একটি বিশাল সুরক্ষা গর্ত কারণ দূষিত ব্যবহারকারীরা কমান্ড-লাইন কমান্ডগুলিতে পরিবেশের পরিবর্তনগুলি নির্ধারণ করতে পারে এবং (সম্ভাব্য) ব্যাপক ক্ষতির কারণ হতে পারে। সাধারণভাবে, কেবল ব্যবহার করবেন না system()। সি লাইব্রেরির মাধ্যমে প্রায়শই আরও ভাল সমাধান প্রয়োগ করা হয়।


3

প্রথম প্যারামিটারটি প্রদত্ত আর্গুমেন্টের সংখ্যা এবং দ্বিতীয় প্যারামিটারটি সেই যুক্তিগুলির প্রতিনিধিত্বকারী স্ট্রিংগুলির একটি তালিকা।



@ ইউজার 362929249 প্রোগ্রামের নাম সহ প্রোগ্রামের নাম। ;)
মাস্টার জেমস

1

দুজনেই

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

সি বা সি ++ প্রোগ্রামের জন্য প্রবেশ পয়েন্টের আইনী সংজ্ঞা। স্ট্রাস্ট্রাপ: সি ++ স্টাইল এবং টেকনিক টেকনিক্যাল এফকিউতে আপনার মূল ফাংশনের জন্য সম্ভব বা আইনী কিছু বৈচিত্রের বিবরণ দেয়।


4
অকার্যকর রাখতে পারে ... int main()int main(void)সামঞ্জস্যতা এবং পঠনযোগ্যতার জন্য ==> ...। আমি জানি না যে সি এর সমস্ত পুরানো সংস্করণ শূন্যতার ক্রিয়াটিকে ঘোষণায় একটি খালি প্যারামিটার তালিকা রাখতে দেয় কিনা।
dylnmc

1
@dylnmc এটি কোনও পঠনযোগ্যতা লাভ দেয় না এবং সমস্ত সি ++ সংস্করণে একেবারে সমান। কেবল সিতে এটির একটি পার্থক্য রয়েছে, তবে কেবল ঘোষণায়, সংজ্ঞায় নয়।
রুসলান

@ রুসলান দুঃখিত, আমি যখন সবেমাত্র সি শিখছিলাম তখন আমি এটি পোস্ট করেছি এবং আমি সম্ভবত এটি পড়তে পেরেছিলাম যে সি এর প্রথম দিকের সংস্করণগুলিতে সিটির voidপ্রয়োজনীয়তা রয়েছে। সে সম্পর্কে আমাকে উদ্ধৃত করবেন না, এবং আমি এখন জানি এটি একটি সামান্য বোকাম মন্তব্য। যদিও এটি আঘাত করতে পারে না।
dylnmc

আরগসি <3 যদি ত্রুটি ফেরায় তবে কী হবে? কী ভুল হতে পারে?
এভিআই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.