C 言語におけるコマンドライン引数の解析

CBeginner
オンラインで実践に進む

はじめに

この実験では、C プログラミングにおいてコマンドライン引数を解析する方法を学びます。この実験では、コマンドライン引数の基本概念を扱い、引数の数の取得、引数値の取得、無効な引数の処理、および単純なコマンドライン ツールの実装を含みます。この実験が終了するとき、C プログラムでコマンドライン引数を扱う方法を十分に理解しているようになります。

コマンドライン引数を理解する

このステップでは、C プログラミングにおけるコマンドライン引数の基本概念と、プログラムが実行される際にどのように渡されるかを学びます。

コマンドライン引数とは?

コマンドライン引数は、コマンドラインからプログラムが起動される際に渡されるパラメータです。C では、これらの引数は main() 関数によって 2 つの特別なパラメータ argcargv を通じて受け取られます。

  1. ~/project ディレクトリに新しいファイル arguments_intro.c を作成します。
cd ~/project
touch arguments_intro.c
  1. コマンドライン引数を調べるために次のコードを追加します。
#include <stdio.h>

int main(int argc, char* argv[]) {
    printf("Number of arguments: %d\n", argc);

    for (int i = 0; i < argc; i++) {
        printf("Argument %d: %s\n", i, argv[i]);
    }

    return 0;
}
  1. プログラムをコンパイルします。
gcc arguments_intro.c -o arguments_intro
  1. 異なる数の引数でプログラムを実行します。
./arguments_intro
./arguments_intro Hello
./arguments_intro Hello World

出力例:

## 引数が提供されていない場合
Number of arguments: 1
Argument 0:./arguments_intro

## 1 つの引数の場合
Number of arguments: 2
Argument 0:./arguments_intro
Argument 1: Hello

## 2 つの引数の場合
Number of arguments: 3
Argument 0:./arguments_intro
Argument 1: Hello
Argument 2: World

argcargv を理解する

  • argc(引数の数):プログラムに渡された引数の総数を表し、プログラム名自体も含みます。
  • argv(引数のベクトル):実際の引数を含む文字列の配列。
  • argv[0] は常にプログラム名です。
  • その後の引数は argv[1] から始まります。

引数の数にアクセスする

このステップでは、argc パラメータを使用して C プログラムに渡された引数の数を取得して利用する方法を学びます。

引数の数を確認する

引数の数をどのように確認するかを理解することは、柔軟で堅牢なコマンドライン プログラムを作成するために重要です。引数の数を検証し、適切なフィードバックを提供する方法を学びます。

  1. ~/project ディレクトリに新しいファイル argument_count.c を作成します。
cd ~/project
touch argument_count.c
  1. 引数の数の確認を示すために次のコードを追加します。
#include <stdio.h>

int main(int argc, char* argv[]) {
    // 正しい数の引数が提供されているかどうかを確認する
    if (argc < 2) {
        printf("エラー: 少なくとも 1 つの引数が必要です。\n");
        printf("使用法:%s <引数 1> [引数 2]...\n", argv[0]);
        return 1;
    }

    // 引数の総数を表示する
    printf("引数の総数:%d\n", argc);

    // 引数の最大数をチェックする
    if (argc > 4) {
        printf("警告:引数が多すぎます。最初の 3 つのみ処理されます。\n");
    }

    return 0;
}
  1. プログラムをコンパイルします。
gcc argument_count.c -o argument_count
  1. 異なる数の引数でプログラムを実行します。
## 引数なし
./argument_count

## 1 つの引数
./argument_count Hello

## 複数の引数
./argument_count Hello World Lab

## 引数が多すぎる
./argument_count Arg1 Arg2 Arg3 Arg4 Arg5

出力例:

## 引数なし
エラー: 少なくとも 1 つの引数が必要です。
使用法:./argument_count <引数1> [引数2]...

## 1 つの引数
引数の総数: 2

## 複数の引数
引数の総数: 4

## 引数が多すぎる
引数の総数: 6
警告: 引数が多すぎます。最初の 3 つのみ処理されます。

重要な概念

  • argc は、プログラム名を含む引数の総数を示します。
  • argc を使用して引数の数を検証できます。
  • 引数が誤って与えられた場合には、明確な使用方法の指示を提供します。
  • 引数が少なすぎる場合や多すぎる場合を上手に処理します。

引数の値を取得する

このステップでは、C プログラムにおいて argv 配列を使用して個々の引数値を取得して処理する方法を学びます。

引数の取得と処理

特定の引数値をどのように取得するかを理解することは、ユーザー入力を効果的に処理できる対話型コマンドライン ツールを作成するために不可欠です。

  1. ~/project ディレクトリに新しいファイル argument_values.c を作成します。
cd ~/project
touch argument_values.c
  1. 引数値の取得を示すために次のコードを追加します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[]) {
    // 少なくとも 2 つの引数が提供されているかどうかを確認する
    if (argc < 3) {
        printf("使用法:%s <名前> <年齢>\n", argv[0]);
        return 1;
    }

    // 引数値を取得して格納する
    char* name = argv[1];
    int age = atoi(argv[2]);

    // 年齢を検証する
    if (age <= 0) {
        printf("エラー: 年齢は正の数でなければなりません。\n");
        return 1;
    }

    // 引数値を処理して表示する
    printf("名前:%s\n", name);
    printf("年齢:%d\n", age);

    // 文字列比較を示す
    if (strcmp(name, "LabEx") == 0) {
        printf("ようこそ、LabEx ユーザー!\n");
    }

    return 0;
}
  1. プログラムをコンパイルします。
gcc argument_values.c -o argument_values
  1. 異なる引数でプログラムを実行します。
## 正しい使用法
./argument_values LabEx 25

## 誤った使用法
./argument_values
./argument_values John
./argument_values John -5

出力例:

## 正しい使用法
名前: LabEx
年齢: 25
ようこそ、LabEx ユーザー!

## 誤った使用法 (引数なし)
使用法:./argument_values <名前> <年齢>

## 誤った使用法 (年齢が欠けている)
使用法:./argument_values <名前> <年齢>

## 誤った使用法 (無効な年齢)
名前: John
エラー: 年齢は正の数でなければなりません。

重要な概念

  • argv[1], argv[2] などは、特定の引数値にアクセスします。
  • atoi() は文字列を整数に変換します。
  • strcmp() は文字列を比較します。
  • 入力引数は常に検証し、クリーンアップします。

無効な引数を処理する

このステップでは、C プログラムにおいて、さまざまな種類の無効な入力シナリオを管理するための、堅牢な引数検証とエラー処理を実装する方法を学びます。

包括的な引数検証

予期しない動作を防ぎ、明確なエラー メッセージを提供するために、ユーザーが提供した引数を慎重に検証することが必要です。信頼性の高いコマンドライン ツールを作成するには、これが不可欠です。

  1. ~/project ディレクトリに新しいファイル argument_validation.c を作成します。
cd ~/project
touch argument_validation.c
  1. 包括的な引数検証を示すために次のコードを追加します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// 文字列が有効な数字かどうかをチェックする関数
int is_numeric(const char* str) {
    while (*str) {
        if (!isdigit(*str)) {
            return 0;
        }
        str++;
    }
    return 1;
}

int main(int argc, char* argv[]) {
    // 引数の数が正しいかどうかをチェックする
    if (argc!= 3) {
        fprintf(stderr, "使用法:%s <ユーザー名> <年齢>\n", argv[0]);
        fprintf(stderr, "エラー: 正確に 2 つの引数が必要です。\n");
        return 1;
    }

    // ユーザー名を検証する
    char* username = argv[1];
    if (strlen(username) < 3 || strlen(username) > 20) {
        fprintf(stderr, "エラー: ユーザー名は 3 文字以上 20 文字以下でなければなりません。\n");
        return 1;
    }

    // 年齢を検証する
    char* age_str = argv[2];
    if (!is_numeric(age_str)) {
        fprintf(stderr, "エラー: 年齢は正の数でなければなりません。\n");
        return 1;
    }

    int age = atoi(age_str);
    if (age < 0 || age > 120) {
        fprintf(stderr, "エラー: 年齢は 0 以上 120 以下でなければなりません。\n");
        return 1;
    }

    // 有効な引数を処理する
    printf("ユーザー名検証済み:%s\n", username);
    printf("年齢検証済み:%d\n", age);

    return 0;
}
  1. プログラムをコンパイルします。
gcc argument_validation.c -o argument_validation
  1. さまざまな入力シナリオでプログラムを実行します。
## 正しい使用法
./argument_validation JohnDoe 30

## 引数の数が誤っている
./argument_validation
./argument_validation JohnDoe

## 無効なユーザー名
./argument_validation Jo 30
./argument_validation JohnDoeWithAVeryLongUsername 30

## 無効な年齢
./argument_validation JohnDoe abc
./argument_validation JohnDoe -5
./argument_validation JohnDoe 150

出力例:

## 正しい使用法
ユーザー名検証済み: JohnDoe
年齢検証済み: 30

## 引数の数が誤っている
使用法:./argument_validation <ユーザー名> <年齢>
エラー: 正確に 2 つの引数が必要です。

## 無効なユーザー名
エラー: ユーザー名は 3 文字以上 20 文字以下でなければなりません。

## 無効な年齢形式
エラー: 年齢は正の数でなければなりません。
エラー: 年齢は 0 以上 120 以下でなければなりません。

重要な概念

  • 引数の形式をチェックするためにカスタム検証関数を使用する
  • 複数の検証チェックを実装する
  • エラー メッセージに stderr を使用する
  • 明確で情報の豊富なエラー フィードバックを提供する
  • 無効な入力に対して非ゼロの終了コードを返す

簡単なコマンドラインツールを実装する

このステップでは、コマンドライン引数の解析と処理に関する学んだスキルを示す実用的なコマンドライン ツールを作成します。

電卓コマンドライン ツール

ユーザーが提供する引数に基づいて基本的な算術演算を行うシンプルなコマンドライン電卓を実装します。

  1. ~/project ディレクトリに新しいファイル calc.c を作成します。
cd ~/project
touch calc.c
  1. コマンドライン電卓を作成するために次のコードを追加します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 関数プロトタイプ
double add(double a, double b);
double subtract(double a, double b);
double multiply(double a, double b);
double divide(double a, double b);

int main(int argc, char* argv[]) {
    // 引数の数が正しいかどうかをチェックする
    if (argc!= 4) {
        fprintf(stderr, "使用法:%s <演算> <数 1> <数 2>\n", argv[0]);
        fprintf(stderr, "演算:add, sub, mul, div\n");
        return 1;
    }

    // 演算を解析する
    char* operation = argv[1];

    // 引数を数値に変換する
    double num1 = atof(argv[2]);
    double num2 = atof(argv[3]);

    // 演算に基づいて計算を行う
    double result = 0;
    if (strcmp(operation, "add") == 0) {
        result = add(num1, num2);
        printf("%.2f + %.2f = %.2f\n", num1, num2, result);
    } else if (strcmp(operation, "sub") == 0) {
        result = subtract(num1, num2);
        printf("%.2f - %.2f = %.2f\n", num1, num2, result);
    } else if (strcmp(operation, "mul") == 0) {
        result = multiply(num1, num2);
        printf("%.2f * %.2f = %.2f\n", num1, num2, result);
    } else if (strcmp(operation, "div") == 0) {
        // ゼロ除算をチェックする
        if (num2 == 0) {
            fprintf(stderr, "エラー: ゼロ除算\n");
            return 1;
        }
        result = divide(num1, num2);
        printf("%.2f / %.2f = %.2f\n", num1, num2, result);
    } else {
        fprintf(stderr, "エラー: 無効な演算\n");
        fprintf(stderr, "サポートされる演算:add, sub, mul, div\n");
        return 1;
    }

    return 0;
}

// 算術演算関数
double add(double a, double b) {
    return a + b;
}

double subtract(double a, double b) {
    return a - b;
}

double multiply(double a, double b) {
    return a * b;
}

double divide(double a, double b) {
    return a / b;
}
  1. プログラムをコンパイルします。
gcc calc.c -o calc
  1. 異なる演算で電卓を実行します。
## 加算
./calc add 5 3

## 減算
./calc sub 10 4

## 乗算
./calc mul 6 7

## 除算
./calc div 15 3

## エラー ケース
./calc div 10 0
./calc pow 5 2

出力例:

## 加算
5.00 + 3.00 = 8.00

## 減算
10.00 - 4.00 = 6.00

## 乗算
6.00 * 7.00 = 42.00

## 除算
15.00 / 3.00 = 5.00

## ゼロ除算
エラー: ゼロ除算

## 無効な演算
エラー: 無効な演算
サポートされる演算: add, sub, mul, div

重要な概念

  • 引数解析と機能ロジックを組み合わせる
  • さまざまな演算シナリオを処理する
  • 明確なエラー メッセージを提供する
  • 異なる演算に対して別々の関数を使用する
  • 入力を検証し、エッジケースを処理する

まとめ

この実験では、C プログラミングにおいてコマンドライン引数を解析する方法を学びます。まず、main() 関数内の argcargv パラメータを含むコマンドライン引数の基本概念を理解します。次に、引数の数を取得し、その値を取得する方法を学びます。また、無効な引数の処理を検討し、シンプルなコマンドライン ツールを実装します。この実験が終了するまでに、C プログラムでコマンドライン引数を効果的に活用する知識とスキルを身につけることができます。