こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

コマンドラインから引数を渡すことについて

-----------------------------------------------
#include<stdio.h>
#include<stdlib.h>

int main(int argc,char *argv[ ])
{
FILE *fin,*fout;
char ss[256];

if(argc != 3){
printf("引数の数が違います\n");
exit(1);
}

if((fin=fopen(argv[1],"r"))==NULL){
printf("入力ファイルをオープンできません\n");
exit(1);
}

if((fout=fopen(argv[2],"w"))==NULL){
printf("出力ファイルをオープンできません\n");
exit(1);
}

while(fgets(ss,256,fin)!=NULL){
fputs(ss,fout);
}

fclose(fin);
fclose(fout);

return 0;
}
-----------------------------------------------

以上のプログラム名は「tcopy.cpp」でコマンドプロンプトから実行し、ファイルをコピーするという事を行っていきます。
「aaa.txt」と「bbb.txt」の2つを用意し、「aaa.txt」の内容、

abcdef
ABCDEF
012345

を「bbb.txt」にコピーしていきます。
そこで疑問なのですが、ファイルをコピーする際、コマンドプロンプトから、

>tcopy aaa.txt bbb.txt

と打ち込むとコピー出来るようであり、「tcopy」、「aaa.txt」、「bbb.txt」が引数になるという事なのですが、何故この3つが引数になるのかという事と、

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

のargcに引数が何故代入されるかが分かりません。
後、「aaa.txt」と「bbb.txt」がargv[1]とargv[2]に何故対応しているかが分かりません。
教えていただければ嬉しいです。

投稿日時 - 2009-03-20 04:42:33

QNo.4811551

すぐに回答ほしいです

質問者が選んだベストアンサー

argv[0] がプログラムを呼んだ時の名前です。
元々、UNIX から来ている言語なので、
別名で登録した時に(ln や、ln -s)
違う動作ができるようになっていたりします。

その後の引数は、自分でいれた引数なのでわかるとは思いますが、
基本的に空白文字で、文字列を区切るようになっています。
これが、呼び出した側の shell が区切るのか、プログラムのスタートアップで区切るのかまでは規定されていませんが、
受け取った main 関数には、区切られた文字列と、その個数が渡される様に、規格で決まっています。
最初から分けられていたり、個数がわかった方が、コマンドラインからの場合、楽だからじゃないでしょうか。

区切られていない、もともとのコマンドラインの文字列も調べられる物も多いですが、
通常使うほどの事はないので、特別な操作が必要だったりします。
(ないものもありますし)

昔は、
main(argc,argv,env)
int argc;
char **argv;
char **env;
{
とはじまり、argv[],env[] の最後は NULL だったので
わざわざ、argc は必要なかったのですが・・・あったらあったで、引数の個数がすぐ分かるので便利だったのでしょう。

投稿日時 - 2009-03-20 21:52:14

お礼

ご回答ありがとうございます。

argv[0]="tcopy"
argv[1]="aaa.txt"
argv[2]="bbb.txt"

argc=個数

>main 関数には、区切られた文字列と、その個数が渡される様に、規格で
>決まっています。

以上の記述により理解できました!
ありがとうございます。

投稿日時 - 2009-03-22 02:06:28

ANo.5

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.4

#3です。一部誤記がありましたので、#3の内容を次のとおり差し替えます。

>argcに引数が何故代入されるかが分かりません。

argcに入るのは「引数の数」です。今回の例でいうと、
1)tcopyという、実行ファイルの名前
2)aaa.txtという、入力ファイルの名前
3)bbb.txtという、出力ファイルの名前
の3個です。

argcが3ですので、argv[]に対しては
argv[0], argv[1], argv[2] の3個にアクセスできます。

投稿日時 - 2009-03-20 18:50:17

ANo.3

>argcに引数が何故代入されるかが分かりません。

argvに入るのは「引数の数」です。今回の例でいうと、
1)tcopyという、実行ファイルの名前
2)aaa.txtという、入力ファイルの名前
3)bbb.txtという、出力ファイルの名前
の3個です。

argvが3ですので、argv[]に対しては
argv[0], argv[1], argv[2] の3個にアクセスできます。

投稿日時 - 2009-03-20 18:48:16

お礼

ご回答ありがとうございます。

>argvに入るのは「引数の数」です。

引数の数が入るということ理解できました!
ありがとうございます。

投稿日時 - 2009-03-22 01:59:25

こんにちは。

私も詳しいことは知りませんので、#1さんと同様に、
  「C言語の言語仕様として、そのように取り決められている」から
というぐらいのお答えしかできませんが、
その辺りのことは、下記の各リンク先の記事が参考になるかと思います。

■過去ログ(関連記事)
C言語でのコマンドライン引数の内部での処理のされ方
http://okwave.jp/qa3103747.html

■参考サイト
もう一度基礎からC言語 第17回 コマンドライン引数と終了コード~main関数の基本事項 終了コードを返す
http://www.grapecity.com/japan/powernews/column/clang/017/page01.htm

<補足>
上記の参考サイトに記載されていますが、C/C++等で作ったプログラムの起動時は、

  OS(シェルプログラム)
    ↓
  プログラム
   ◎スタートアップルーチン ←※これはリンク時に自動的に結合されます。
     ↓ ・ここでコマンドラインの解析が行われ、引数(argc, argv)に格納してmain関数を呼び出す。
     ↓
   ◎main関数
     ↓ ・渡された引数(argc, argv)を参照して処理を行う。
     ↓
   ◎その他の関数

というような流れで実行されているようです。
※ただし、これは処理系に依存する部分だと思います。

投稿日時 - 2009-03-20 09:31:54

お礼

ご回答ありがとうございます。

参考サイトや<補足>により、イメージが出来ました!
ありがとうございます。

投稿日時 - 2009-03-22 01:50:04

ANo.1

質問の趣旨を誤解しているかも知れませんが

main 関数の仕様として、そのように用意する事が定められているから、その様に用意してある。
その様に用意してあるから、用意してある機能を用意された通りに利用することが出来る。
というだけの事ですよ。

投稿日時 - 2009-03-20 05:47:43

お礼

ご回答ありがとうございます。

>main 関数の仕様として、そのように用意する事が定められているから、そ
>の様に用意してある。
>その様に用意してあるから、用意してある機能を用意された通りに利用する
>ことが出来る。

そういうものだと、理解するということですね!
ありがとうございます。

投稿日時 - 2009-03-22 01:43:00

あなたにオススメの質問