dポイントプレゼントキャンペーン実施中!

はじめまして。

C言語を学習しています。

PCのOSはWindows XPです。

参考書に、アプリケーションの動作を指定するオプションを指定する方法として、下記の説明とプログラムが載っています。

以下の点でつまづいており、ご教示をお願い致します。

1、プログラム実行結果画面(コマンドプロンプトのような黒い画面。スクリーンショットを添付しております。)に【-a】と入力しようとしましたが、テンキーの【-】を押した時点で画面が消えてしまいます。
どのように操作すれば、参考書のような実行結果が得られるのでしょうか。

2、【argc--;】の部分で、ここでなぜデクリメントを使うのでしょうか。

3、argvは文字配列へのポインタ変数とのことですが、if文のところの【argv[argc][0]】が何を意味しているのか教えてください。
argv[配列の要素]のような書き方ではなく、argvの横に[]が2つある時点で混乱してしまいます。

どうかよろしくお願い致します。


●参考書による説明

一般的に、コマンドラインにはファイル名の他に、アプリケーションの動作を指定するオプションを指定することがあります。

例えば、Windowsでファイル名を指定して実行で defrag と指定して起動すると、デフラグが起動して何もせずに終了しますが、
defrag c: と指定すると、Cドライブのデフラグを開始します。
また、defrag c: -a と指定すると、Cドライブの分析結果だけを表示します。
このような使い方は、パソコン上級者にはおなじみのやり方です。

この例では、 c: と -a という2つの文字列がコマンドラインに渡され、それをアプリケーション内で解析して、動作を決定しています。

同様のことは、コマンドラインの文字列を調べれば簡単にわかります。
ここでは、-a と -s というオプションの有無を解析する例です。



●プログラム

#include <stdio.h>

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

while (argc > 0) {

argc--;

if (argv[argc][0] == '-') {
if (argv[argc][1] == 'a') printf("-a オプション\n");
if (argv[argc][1] == 's') printf("-s オプション\n");
}
}

return 0;
}

このプログラムに -a -s というオプションを与えて実行した結果は次の通りです。

-a オプション
-s オプション

同様にすれば、いくつのオプションにでも対応することができます。
また、先頭が - ではない文字列をファイル名として扱うようにすれば、
ファイル名も前項と同様に取得することができます。

「C言語 コマンドラインの文字列を調べる方」の質問画像

A 回答 (3件)

コマンドラインというのは、「実行するときに指定」するものです。


例えば
XXXXX.exe -a -s
等というように。

別質問でfgetsで読みこんだような、「実行しててから入力」ではありません。
こっちは
XXXXX.exe ←コマンドライン
-a ← ここはプログラム実行中
-s ← ここはプログラム実行中
という感じです。


今、Visual Studio を使っていて、いるのではないでしょうか?
Visual Studioから「実行」「デバッグ実行」した場合、標準では後者のような「コマンドライン引数無し」の状態で実行します。
この後に 「-」 とキー入力しても、既にプログラムは実行されているので「コマンドライン引数」にはなりません。
さらに、その画面表示は、プログラムが終了した状態です。

コマンドライン引数を指定するには、プロジェクトのプロパティの「デバッグ」欄から行います。

あるいは、コマンドプロンプトから、引数を付けて実行します。
標準では、プロジェクトの下のDebugまたはReleaseフォルダに実行ファイルができるので、CDコマンドで実行ファイルのあるフォルダに移動して
実行ファイル 引数
の形で実行してください。
こちらの方法だと、引数を変えて実行するのも簡単なので、引数を変えたら、結果がどうなるかいろいろ試して理解してください。


(2)
int main(int argc, char * argv[])
とすると
argc: argvの長さ=実行コマンドと引数の数
argv: 実行コマンド(argv[0])と引数(argv[1]~)
となります。
char* argv[argc] ;
と配列宣言したようなイメージです。

argcをそのまま変更しているからややこしいので、次のように変えます。
int a = argc ;
while (a > 0) {
a--;
printf("a: %d , argc: %d\n",a,argc);
if (argv[a][0] == '-') {
if (argv[a][1] == 'a') printf("-a オプション\n");
if (argv[a][1] == 's') printf("-s オプション\n");
}
}
これなら、デクリメントする意味がわかるのでは無いでしょうか?

※ でもなんで、後からやるんだろう?
引数は先頭から処理するのが普通ですし
for( a=1; a<argc ; a++ ){ argvの処理 }
とかの方がわかりやすいと思うのですが。
※※ 前回の質問のと合せて、その参考書、サンプルコードがあまりよくない気がします。

(3)
配列、ポインタのことは、よく理解してください。この先ずーっとついてまわります。
・関数の定義に使う char * argv[] は char **argv と同じです。
ということは
argv : char ** 型
*(argv+X) / argv[X] : char *型
*(*(argv+X)+Y) / argv[X][Y] : char 型
→ char* argvX = *(argv+X) ; とすると
*(argvX+Y) / argvX[Y] : char 型
です。混乱したら、一つずつ分解して、順番に考えることです。
    • good
    • 0
この回答へのお礼

ご回答いただき、ありがとうございました。

お礼日時:2012/08/17 21:24

こんにちは。



 下記サイトにコマンドライン文字列がどのようにargvに格納されるかが載っています。
  http://ratan.dyndns.info/MicrosoftVisualC++/file …

では。
    • good
    • 0
この回答へのお礼

ご回答いただき、ありがとうございました。

お礼日時:2012/08/17 21:25
    • good
    • 0
この回答へのお礼

ご回答いただき、ありがとうございました。

お礼日時:2012/08/17 21:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!