UNIXライクシステムでのコマンドラインオプションの解析

はじめに



コンソールであれグラフィカルであれ、プログラムの重要なタスクの1つは、コマンドライン引数の解釈です。 正式には、引数はコマンドライン上のすべての単語(コマンド自体の名前を含む)を区切り記号 (規則として、これはスペースとタブ)で区切ったものです。引用符を使用すると、引数に区切り記号を含めることができます。

引数は、 オプションオペランドに分けることができます 。 オプションは、プログラムの動作を変更するか、追加情報を提供します。 オプションには、このオプションにのみ必要な情報である独自の引数があります。



ポジシックス



POSIX標準は、UNIXライクシステムでのプログラムの予想される動作を記述しています。 プログラムを作成するとき、だれもあなたが標準に厳密に従うことを強制することはありませんが、これはユーザーの生活を楽にするので良い考えです。 チームの議論に関する基本的なルールは次のとおりです。





長いオプション



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;







引数argcargvmain ()関数から直接渡され、 optstringはオプション文字列です。 文字列の文字の後にコロンが続く場合、このオプションは引数を取ります。

getopt()を使用するには、 -1を返すまでループで繰り返し呼び出されます。 有効なオプション文字が見つかるたびに、関数はその文字を返します。 オプションが引数を取る場合、そのポインターはoptarg変数に置かれます。

optind変数は、現在のインデックスをargvに保存します。 opterr変数ゼロ以外(デフォルトは0 )の場合、 getopt()自体は、無効なオプションまたは引数がない場合にメッセージを表示します。 opterrがゼロの場合、エラーの場合getopt()「?」を返します または「:」は 、無効なオプションが見つかったか、必要なオプション引数が省略されたかに応じて、検出された無効な文字がoptopt変数に含まれます。

標準のgetopt()関数は、「-」文字で始まらない最初の引数を検出するとすぐに停止することに注意してください。GNUバージョンの関数は、コマンドライン全体からオプションを探します。 GNU関数の動作は変更できます(ただし、これはこの記事の範囲外です)。



getopt()を使用したサンプルプログラム



礼儀iv_s



  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. int main( int argc、 char ** argv){
  5. if (argc == 1){ //引数なしで実行した場合、ヘルプを表示
  6. printf( "getopt test \ n" );
  7. printf( "usage:\ n" );
  8. printf( "opts -an -bm -os \ n" );
  9. printf( "例:\ n" );
  10. printf( "$ opts -a 323 -b 23 -o '-' \ n" );
  11. printf( "323-23 = 300 \ n" );
  12. 0を返します。
  13. }
  14. char * opts = "a:b:o:" ; //利用可能なオプション。それぞれが引数を取ります
  15. int a、b; //ここに数字を保存します
  16. char op; //ここで演算子
  17. int opt; //次の各オプションがここに到達します
  18. while ((opt = getopt(argc、argv、opts))!= -1){ // -1が返されるまでgetoptを呼び出す
  19. switch (opt){
  20. case 'a'// -aオプションの場合、引数を持つ文字列を数値に変換します
  21. a = atoi(optarg);
  22. 休憩 ;
  23. case 'b'// -bにも
  24. b = atoi(optarg);
  25. 休憩 ;
  26. case 'o'//演算子をopに保存します
  27. op = optarg [0];
  28. 休憩 ;
  29. }
  30. }
  31. スイッチ (op){
  32. case '+'// oparator + addなどの場合
  33. printf( "%d +%d =%d \ n" 、a、b、a + b);
  34. 休憩 ;
  35. ケース 「-」
  36. printf( "%d-%d =%d \ n" 、a、b、a-b);
  37. 休憩 ;
  38. ケース '*'
  39. printf( "%d *%d =%d \ n" 、a、b、a * b);
  40. 休憩 ;
  41. ケース '/'
  42. printf( "%d /%d =%d \ n" 、a、b、a / b);
  43. 休憩 ;
  44. }
  45. 0を返します。
  46. }
*このソースコードは、 ソースコードハイライターで強調表示されました。




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つの値を取ることができます。



flag-このポインターがNULLの場合、 getopt_long()valフィールドの値を返し、そうでない場合は0を返し、flagが指す変数にvalの値が設定されます。

val-通常、いくつかの記号定数が含まれます。長いオプションが短いオプションに対応する場合、この定数はoptstring引数に表示されるものと同じでなければなりません。

longopts配列の最後の要素はゼロで埋めなければならないことに注意することが重要です。



getopt_long()を使用したサンプルプログラム



シャッフルの礼儀



  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <getopt.h>
  5. void usage( char * name)
  6. {
  7. printf( "usage:%s \ n \ \ thこのメッセージ\ n \ \ tc [config file] \ n \ \ t-このメッセージを助ける\ n \ \ t-config = config_file \ n"、name);
  8. 帰る
  9. }
  10. int main( int argc、 char * argv [])
  11. {
  12. int c;
  13. while (1){
  14. 静的 構造体オプションlong_opt [] = {
  15. { "ヘルプ" 、0、0、 'h' }、
  16. { "Config" 、1、0、 'c' }、
  17. {0,0,0,0}
  18. };
  19. int optIdx;
  20. if ((c = getopt_long(argc、argv、 "c:h" 、long_opt、&optIdx))== -1)
  21. 休憩 ;
  22. スイッチ (c){
  23. ケース 'h'
  24. 使用法(argv [0]);
  25. return (-1);
  26. ケース 'c'
  27. printf( "オプション 'c'を選択、ファイル名:%s \ n" 、optarg);
  28. return (1);
  29. デフォルト
  30. 使用法(argv [0]);
  31. return (-1);
  32. }
  33. }
  34. return (0);
  35. }
*このソースコードは、 ソースコードハイライターで強調表示されました。




おわりに



この記事では、UNIXライクシステムでコマンドライン引数解析関数を使用する基本について説明します。 この資料はもっと広範囲に及ぶ可能性がありますが、興味のある人なら誰でも自分ですべての微妙さを学び、研究することができます。



この記事は、Arnold Robbinsによる「Linuxプログラミングの例」 ISBN 5-9579-0059-1に基づいて作成されました。






All Articles