0Pricing
C Academy · レッスン

getopt

標準的なオプション解析です。

「getopt」はCoddyKit上の無料C Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。

getopt とは

getopt は、標準的な Unix の慣例に従って、単一文字のオプションを解析してくれる POSIX 関数です。

<unistd.h> に定義されており、フラグを手動で解析するための定型コードの大部分を省けます。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "v")) != -1) {
        if (opt == 'v') printf("verbose on\n");
    }
    return 0;
}

optstring

getopt の 3 番目の引数は optstring で、有効なオプション文字の一覧です。

"abc" は、-a、-b、-c のすべてを真偽値フラグとして受け付けることを意味します。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "abc")) != -1) {
        printf("saw option -%c\n", opt);
    }
    return 0;
}

解析ループ

getopt は呼び出すたびに次のオプション文字を返し、解析が完了すると -1 を返します。

標準的なパターンは、内部に switch を置いた while ループで、返された文字に応じて処理を振り分けます。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "xy")) != -1) {
        switch (opt) {
            case 'x': printf("x set\n"); break;
            case 'y': printf("y set\n"); break;
        }
    }
    return 0;
}

引数を持つオプション

値を取ることを示すには、optstring の文字の後ろにコロンを付けます。"o:" は、-o が引数を必要とすることを意味します。

その値はグローバル変数 optarg から取得できます。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "o:")) != -1) {
        if (opt == 'o') printf("output = %s\n", optarg);
    }
    return 0;
}

フラグと値を取るオプションを組み合わせる

1 つの optstring に、真偽値オプションと値を取るオプションを混在させられます。ここでは -v がフラグ、-n が数値を取るオプションです。

getopt では、-vn 5 のようにフラグをまとめて指定することもできます。

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

int main(int argc, char *argv[]) {
    int opt, verbose = 0, n = 0;
    while ((opt = getopt(argc, argv, "vn:")) != -1) {
        if (opt == 'v') verbose = 1;
        else if (opt == 'n') n = atoi(optarg);
    }
    printf("verbose=%d n=%d\n", verbose, n);
    return 0;
}

未知のオプションを処理する

getopt が optstring にないオプションに遭遇すると、'?' を返し、エラーを出力します(抑制していない場合)。

case '?' を追加して、不正な入力を適切に処理してください。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "a")) != -1) {
        switch (opt) {
            case 'a': printf("a\n"); break;
            case '?': printf("unknown option\n"); break;
        }
    }
    return 0;
}

必須の引数がない場合

値を取るオプションが値なしで指定された場合の getopt の動作は、optstring によって異なります。

optstring の先頭にコロン(":o:")を付けると、引数がない場合に getopt は ':' を返すため、状況を正確に報告できます。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, ":f:")) != -1) {
        if (opt == 'f') printf("file=%s\n", optarg);
        else if (opt == ':') printf("option needs a value\n");
    }
    return 0;
}

optind: 解析の停止位置

ループの終了後、グローバル変数 optind には、最初のオプションではない引数の argv 内のインデックスが格納されています。

これを使って、ファイル名などの残りの位置引数を処理します。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "v")) != -1) { }
    for (int i = optind; i < argc; i++)
        printf("positional: %s\n", argv[i]);
    return 0;
}

getopt のメッセージを抑制する

デフォルトでは、getopt は独自のエラーメッセージを stderr に出力します。グローバル変数 opterr に 0 を設定すると抑制でき、エラーを自分で処理できます。

#include <stdio.h>
#include <unistd.h>

extern int opterr;

int main(int argc, char *argv[]) {
    opterr = 0;
    int opt;
    while ((opt = getopt(argc, argv, "a")) != -1) {
        if (opt == '?') printf("bad option, handled quietly\n");
    }
    return 0;
}

不正なオプションを特定する

getopt が '?' を返した場合、グローバル変数 optopt には問題のあるオプション文字が格納されています。

これにより、どのフラグが間違っていたのかを明示した、わかりやすいメッセージを出力できます。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "a")) != -1) {
        if (opt == '?')
            printf("Unrecognized option: -%c\n", optopt);
    }
    return 0;
}

長いオプションについて

通常の getopt は単一文字のオプションにしか対応していません。--verbose のような長いオプションには、GNU システムが <getopt.h> の getopt_long を提供しています。

同じループを使いますが、長いオプションの記述子テーブルが追加されます。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    printf("getopt parses %d short options\n", argc > 1 ? argc - 1 : 0);
    return 0;
}

理解度チェック

getopt の optstring 構文についての理解度を確認しましょう。

まとめ

getopt を使った標準的なオプション解析を学びました。

  • getopt(argc, argv, optstring) が -1 でない間ループし、switch で処理を振り分けます。
  • 文字の後ろにコロンを付けると値を取ることを示し、その値は optarg に格納されます。
  • optind は、その後の最初の位置引数を指します。
  • グローバル変数 opterr、optopt、先頭のコロンでエラー処理を制御します。

よくある質問

「getopt」レッスンは無料ですか?

はい。「getopt」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。

「getopt」で何を学びますか?

標準的なオプション解析です。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「getopt」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC Academyレッスンでコードを書いて実行できますか?

はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. argc と argv
  2. オプションの解析
  3. getopt
  4. CLI ツールの作成
← C Academyに戻る