🇯🇵 日本語 | 🇺🇸 English

第33回 コマンドライン引数 (argc/argv)

プログラム実行時にパラメータを渡す仕組みを学びましょう。

📖 このページで覚えること
✅ 最低限ここだけ覚える
  • argc は引数の個数。プログラム名も含む
  • argv[0] はプログラム名、ユーザー入力は argv[1] から
  • 引数は文字列なので、数値に使うなら変換が必要
⭐ 余裕があれば読む
  • 引数不足を argc で必ずチェックする
  • atoi より厳密な変換には strtol を使う
  • ファイル名やオプションを渡す実用プログラムに応用する

argc と argv とは

これまで int main(void) と書いてきましたが、main関数は引数を受け取る形でも書けます。
int main(int argc, char *argv[]) {
    // argc: 引数の個数(Argument Count)
    // argv: 引数の文字列配列(Argument Vector)
}
argc
引数の個数(プログラム名を含む
argv[]
各引数の文字列(char*の配列)
例えば ./myprogram hello world と実行すると:
変数意味
argc3引数は3つ
argv[0]"./myprogram"プログラム名
argv[1]"hello"第1引数
argv[2]"world"第2引数
重要: argv[0] はプログラム自身の名前です。ユーザーが渡した引数は argv[1] から始まります。

基本的な使い方

全引数を表示するプログラム:
#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("引数の個数: %d\n", argc);
    for (int i = 0; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
    return 0;
}
$ gcc args.c -o args $ ./args hello world 123 引数の個数: 4 argv[0] = ./args argv[1] = hello argv[2] = world argv[3] = 123

引数を数値として使う

argv の要素は全て文字列(char*)です。数値として使うには変換が必要です。
関数変換先ヘッダ使用例
atoi(s)intstdlib.hint n = atoi(argv[1]);
atof(s)doublestdlib.hdouble d = atof(argv[1]);
atol(s)longstdlib.hlong l = atol(argv[1]);

例: コマンドライン電卓

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

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("使い方: %s 数値1 数値2\n", argv[0]);
        return 1;
    }
    int a = atoi(argv[1]);
    int b = atoi(argv[2]);
    printf("%d + %d = %d\n", a, b, a + b);
    return 0;
}
$ ./calc 15 27 15 + 27 = 42
引数チェックは必須です。argc を確認して、引数が足りない場合は使い方を表示して終了しましょう。

実践例: ファイル名を引数で渡す

実際のプログラムでは、処理対象のファイル名をコマンドライン引数で受け取ることが多いです。
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("使い方: %s ファイル名\n", argv[0]);
        return 1;
    }
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL) {
        printf("ファイル '%s' を開けません\n", argv[1]);
        return 1;
    }
    char line[256];
    while (fgets(line, 256, fp) != NULL) {
        printf("%s", line);
    }
    fclose(fp);
    return 0;
}
$ ./cat scores.txt Taro 80 Hanako 95 Jiro 70
これは UNIX の cat コマンドの簡易版です。

自分で書いてみよう ― argc/argv

コマンドライン引数は「実行時に外から値を渡す」練習をすると使いどころが見えてきます。すべての課題で、まず argc をチェックしましょう。
課題1: 名前つき挨拶
./hello TaroHello, Taro! と表示する。引数がないときは使い方を出す。
課題2: 足し算コマンド
./add 12 30 で 42 を表示する。atoi を使って文字列を整数に変換する。
課題3: 行番号つき cat
ファイル名を1つ受け取り、各行の先頭に行番号をつけて表示する。fopen の失敗も確認する。
間違えたら戻るページ: 入力処理は 第5回 scanf、関数の引数は 第24回 関数(基本)、ファイル処理は 第39回 ファイル入出力 を確認しましょう。

確認クイズ

// 以下のコマンドで実行したとき
// $ ./prog hello world

argc の値はいくつ?

2
3
1
0
解説: argc はプログラム名を含めた引数の個数。./prog, hello, world3つ
argv[0]="./prog", argv[1]="hello", argv[2]="world"。
// $ ./calc 10 20 を実行
int a = atoi(argv[1]);
int b = atoi(argv[2]);
printf("%d\n", a + b);

出力は?

30
1020
エラー
0
解説: atoi("10") → 10、atoi("20") → 20。10 + 20 = 30
atoi を使わないと文字列のまま連結("1020")になるので注意。

関連する講座

関数編
第24回 関数(基本)
main関数を含む、関数の引数と戻り値の基本を確認できます。
発展編
第39回 ファイル入出力
引数で受け取ったファイル名を読み書きする実践例につながります。
実践編
マルチファイル構成・Makefile
コマンドラインでビルド・実行する流れを実践できます。
← 前の講座
第32回 再帰関数
次の講座 →
第34回 ポインタの基礎

この講座の理解を深めるおすすめ書籍

サイトで動きを理解し、書籍で演習量を補うと効果的です

📘
苦しんで覚えるC言語
MMGames 著
初心者向けの定番入門書。
Amazonで見る
📗
新・明解C言語 入門編
柴田望洋 著
図解が豊富で演習問題も充実。
Amazonで見る
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。
Amazonで見る

※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。

この記事をシェア
X(Twitter)でシェア Facebookでシェア LINEで送る はてブ