はじめに
コンソールであれグラフィカルであれ、プログラムの重要なタスクの1つは、コマンドライン
引数の解釈です。 正式には、引数はコマンドライン上のすべての単語(コマンド自体の名前を含む)を
区切り記号 (規則として、これはスペースとタブ)で区切ったものです。引用符を使用すると、引数に区切り記号を含めることができます。
引数は、
オプションと
オペランドに分けることができ
ます 。 オプションは、プログラムの動作を変更するか、追加情報を提供します。 オプションには、このオプションにのみ必要な情報である独自の引数があります。
ポジシックス
POSIX標準は、UNIXライクシステムでのプログラムの予想される動作を記述しています。 プログラムを作成するとき、だれもあなたが標準に厳密に従うことを強制することはありませんが、これはユーザーの生活を楽にするので良い考えです。 チームの議論に関する基本的なルールは次のとおりです。
- プログラム名は2文字以上9文字以下でなければなりません。
- プログラム名は、小文字と数字でのみ記述する必要があります。
- オプション名は、単純な英数字でなければなりません。 桁数の多いオプションは禁止されています。
- すべてのオプションは「-」で始まる必要があります。
- 引数のないオプションの場合、オプションを組み合わせるオプション(たとえば、 foo -a -b -cとfoo -abc )を実装する必要があります。
- オプションの引数は、スペースで区切る必要があります。
- オプション引数はオプションではありません。
- オプションに複数の引数値が必要な場合は、コンマまたは区切り文字で区切られた文字列として渡す必要があります。
- オプションはオペランドの前に置く必要があります。
- 引数「-」は、すべてのオプションの終わりを示します。
- オプションが相互に排他的である場合を除き、オプションの順序が役割を果たすべきではありません。
- 引数の順序は重要かもしれません。
- 名前付きファイルを読み書きするプログラムは、単一の引数「-」をそれぞれ標準入力または標準出力として解釈する必要があります。
長いオプション
GNUプログラムは、POSIXで動作が説明されていない長いオプションも使用します。長いオプションは「-」で始まります。これらのオプションについて、GNUは次の規則も実装します。
- 各短いオプションには、長いオプションの独自のバージョンが必要です。
- 長いオプションは、その一意性を確保して最短ラインに縮小できます。
- 長いオプションの引数は、区切り文字または「=」記号で区切られます。
プログラムのパラメーターはどこから来ますか
ご存じのように、Cの
メイン()関数は次のように定義されています。
int main(int argc, char *argv[])
ここには2つのパラメーターがあります
。argcはコマンドラインの引数の数を決定し、
argvはこれらの引数へのポインターの配列を格納します。
argv [0]は常にコマンドの名前であり、
argv [argc] == NULLであることに注意する必要があり
ます 。これらの2つの事実は開発中に役立ちます。
解析オプション
80年代、Unixサポートチームは、各Unixプログラムがオプションの解析に独自のメソッドを使用していることに気付きました。 これは
getopt()関数の開発を促し、標準の規則に従ったコードを記述しやすくしました。
GNU
getopt_long()関数は
getopt()と互換性があり、長いオプションの解析も容易にします。
getopt
発表:
#include <unistd.h>
int getopt(int argc, char *argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
引数
argcと
argvは
main ()関数から直接渡され、
optstringはオプション文字列です。 文字列の文字の後にコロンが続く場合、このオプションは引数を取ります。
getopt()を使用するには、
-1を返すまでループで繰り返し呼び出されます。 有効なオプション文字が見つかるたびに、関数はその文字を返します。 オプションが引数を取る場合、そのポインターは
optarg変数に置かれます。
optind変数は、現在のインデックスを
argvに保存します。
opterr変数
がゼロ以外(デフォルトは
0 )の場合、
getopt()自体は、無効なオプションまたは引数がない場合にメッセージを表示します。
opterrがゼロの場合、エラーの場合
getopt()は
「?」を返します
。 または
「:」は 、無効なオプションが見つかったか、必要なオプション引数が省略されたかに応じて、検出された無効な文字が
optopt変数に
含まれます。
標準の
getopt()関数は、「-」文字で始まらない最初の引数を検出するとすぐに停止することに注意してください
。GNUバージョンの関数は、コマンドライン全体からオプションを探します。 GNU関数の動作は変更できます(ただし、これはこの記事の範囲外です)。
getopt()を使用したサンプルプログラム
礼儀
iv_s- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- int main( int argc、 char ** argv){
- if (argc == 1){ //引数なしで実行した場合、ヘルプを表示
- printf( "getopt test \ n" );
- printf( "usage:\ n" );
- printf( "opts -an -bm -os \ n" );
- printf( "例:\ n" );
- printf( "$ opts -a 323 -b 23 -o '-' \ n" );
- printf( "323-23 = 300 \ n" );
- 0を返します。
- }
- char * opts = "a:b:o:" ; //利用可能なオプション。それぞれが引数を取ります
- int a、b; //ここに数字を保存します
- char op; //ここで演算子
- int opt; //次の各オプションがここに到達します
- while ((opt = getopt(argc、argv、opts))!= -1){ // -1が返されるまでgetoptを呼び出す
- switch (opt){
- case 'a' : // -aオプションの場合、引数を持つ文字列を数値に変換します
- a = atoi(optarg);
- 休憩 ;
- case 'b' : // -bにも
- b = atoi(optarg);
- 休憩 ;
- case 'o' : //演算子をopに保存します
- op = optarg [0];
- 休憩 ;
- }
- }
- スイッチ (op){
- case '+' : // oparator + addなどの場合
- printf( "%d +%d =%d \ n" 、a、b、a + b);
- 休憩 ;
- ケース 「-」 :
- printf( "%d-%d =%d \ n" 、a、b、a-b);
- 休憩 ;
- ケース '*' :
- printf( "%d *%d =%d \ n" 、a、b、a * b);
- 休憩 ;
- ケース '/' :
- printf( "%d /%d =%d \ n" 、a、b、a / b);
- 休憩 ;
- }
- 0を返します。
- }
*このソースコードは、 ソースコードハイライターで強調表示されました。
getopt_long()
発表:
#include <getopt.h>
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex);
最初の3つの引数は
getopt()と
同じです
。longoptsは長いオプションの配列へのポインタです
。longindexは、検出された長いオプションのインデックスが
longoptsに
配置される変数を指し
ます 。必要ない場合は
NULLにでき
ます 。
オプション構造は次のように定義されます。
struct option
{
const char *name;
int has_arg;
int *flag;
int val;
}
name-ダッシュを前に付けないオプションの名前。
has_arg-名前が示すとおり、変数はlongオプションに引数があるかどうかを示し、3つの値を取ることができます。
- 0-引数を受け入れません。
- 1-必須の引数。
- 2はオプションの引数です。
flag-このポインターが
NULLの場合、
getopt_long()は
valフィールドの値を返し、そうでない場合は
0を返し、flagが指す変数に
valの値が設定されます。
val-通常、いくつかの記号定数が含まれます。長いオプションが短いオプションに対応する場合、この定数は
optstring引数に表示されるものと同じでなければなりません。
longopts配列の最後の要素はゼロで埋めなければならないことに注意することが重要です。
getopt_long()を使用したサンプルプログラム
シャッフルの礼儀
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <getopt.h>
- void usage( char * name)
- {
- printf( "usage:%s \ n \ \ thこのメッセージ\ n \ \ tc [config file] \ n \ \ t-このメッセージを助ける\ n \ \ t-config = config_file \ n"、name);
- 帰る
- }
- int main( int argc、 char * argv [])
- {
- int c;
- while (1){
- 静的 構造体オプションlong_opt [] = {
- { "ヘルプ" 、0、0、 'h' }、
- { "Config" 、1、0、 'c' }、
- {0,0,0,0}
- };
- int optIdx;
- if ((c = getopt_long(argc、argv、 "c:h" 、long_opt、&optIdx))== -1)
- 休憩 ;
- スイッチ (c){
- ケース 'h' :
- 使用法(argv [0]);
- return (-1);
- ケース 'c' :
- printf( "オプション 'c'を選択、ファイル名:%s \ n" 、optarg);
- return (1);
- デフォルト :
- 使用法(argv [0]);
- return (-1);
- }
- }
- return (0);
- }
*このソースコードは、 ソースコードハイライターで強調表示されました。
おわりに
この記事では、UNIXライクシステムでコマンドライン引数解析関数を使用する基本について説明します。 この資料はもっと広範囲に及ぶ可能性がありますが、興味のある人なら誰でも自分ですべての微妙さを学び、研究することができます。
この記事は、Arnold Robbinsによる「Linuxプログラミングの例」
ISBN 5-9579-0059-1に基づいて作成されました。