C 言語で optind 変数が割り当てられる方法

  1. getopt 関数を使用して、C 言語でコマンドラインオプションを解析する
  2. optind および optarg 変数を使用して、C 言語で argv 要素を処理する

この記事では、C 言語で optind 変数がどのように割り当てられるかについての複数の方法を示します。

getopt 関数を使用して、C 言語でコマンドラインオプションを解析する

UNIX ベースのシステムの一般的なコマンドラインプログラムは、引数とオプションを取ります。オプションは通常、ハイフンに続く文字で指定され、一意の各文字は、指定された引数に関する情報を示すか、実行されるプログラムの特定の動作を生成します。オプションには、必須またはオプションの引数を含めることができます。後者の場合、プログラムでは 1つのハイフンの後にオプションをグループ化できるのが一般的であり、コマンドの最後に引数のみを渡すことができます。

getopt 関数は、オプションを解析し、プログラムから指定された引数を取得し、入力に基づいて対応するコードパスを実行するために使用されます。getopt は 3つの引数を取り、最初の 2つは main 関数に渡される argcargv です。3 番目の引数は optstring です。これは、正当なオプション文字を表す文字列へのポインタです。getopt は、すべてのオプションが取得されるまで連続して呼び出す必要があります。

次の例では、p および x 文字のオプションを使用するプログラムを示します。optstring はコロンで始まることに注意してください。これは、欠落している引数が見つかったときに getopt 呼び出しによって返される必要がある値を示します。また、文字の後に指定されたコロン(例:p)は、オプションに引数が必要であることを示します。2つのコロンは、引数がオプションであることを意味します。同じオプション文字をコマンドラインで複数回渡すことができます。getopt 関数は、成功した場合はオプション文字を返し、検出されたオプション文字が optstring にない場合は文字 ? を返します。

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

int main(int argc, char *argv[]) {
    int opt, xnum = 0;
    char *pstr = NULL;

    while ((opt = getopt(argc, argv, ":p:x")) != -1) {
        printf("opt = %3d (%c); optind = %d\n", opt, opt, optind);

        switch (opt) {
            case 'p': pstr = optarg;        break;
            case 'x': xnum++;               break;
            case ':': fprintf(stderr, "Missing argument!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            case '?': fprintf(stderr, "Unrecognized option!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            default:  fprintf(stderr, "Unexpected case in switch()"); exit(EXIT_FAILURE);
        }
    }

    exit(EXIT_SUCCESS);
}

サンプルコマンド:

./program_name -p hello -p there

出力:

opt = 112 (p); optind = 3
opt = 112 (p); optind = 5

optind および optarg 変数を使用して、C 言語で argv 要素を処理する

前のコードサンプルは、典型的な getopt の使用法を示しています。この場合、関数は while ループ式からエラーコード -1 を返すまで呼び出されます。一方、switch ステートメントは、対応するコードブロックを実行するために可能な getopt 戻り値をチェックします。optind 変数は argv 内の次の要素のインデックスを表し、getopt を最初に呼び出す前に 1 に初期化されることに注意してください。一方、optarg は、現在のオプション文字に続く引数を指す外部変数です。オプションに引数が含まれていない場合、optarg はゼロに設定されます。次のコード例は、optarg 変数が指す引数を保存し、必要に応じて操作する方法を示しています。引数はスペース区切り文字なしでオプションに従うことができることに注意してください。

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

int main(int argc, char *argv[]) {
    int opt, xnum = 0;
    char *pstr = NULL;

    while ((opt = getopt(argc, argv, ":p:x")) != -1) {
        printf("opt = %3d (%c); optind = %d\n", opt, opt, optind);

        switch (opt) {
            case 'p': pstr = optarg;        break;
            case 'x': xnum++;               break;
            case ':': fprintf(stderr, "Missing argument!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            case '?': fprintf(stderr, "Unrecognized option!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            default:  fprintf(stderr, "Unexpected case in switch()"); exit(EXIT_FAILURE);
        }
    }

    if (xnum != 0)
        printf("-x was specified (count=%d)\n", xnum);
    if (pstr != NULL)
        printf("-p was specified with the value \"%s\"\n", pstr);
    if (optind < argc)
        printf("First non-option argument is \"%s\" at argv[%d]\n",
               argv[optind], optind);

    exit(EXIT_SUCCESS);
}

サンプルコマンド:

./program_name -p hello

出力:

opt = 112 (p); optind = 3
-p was specified with the value "hello"