C言語で作ったプログラムは、実行時に外部から情報を受け取ることができます。コマンドプロンプトやターミナルでプログラムを起動する際に、ファイル名やオプションなどを渡す、あの機能です。これを**「コマンドライン引数」**と呼びます。
この記事では、main
関数が持つargc
とargv
という特別な引数を使って、プログラムに外部から情報を渡す方法と、その情報を活用するためのテクニックを分かりやすく解説します。
main
関数の特別な引数 argc
と argv
コマンドライン引数を受け取るために、main
関数は以下のように2つの引数を持つ形で定義します。
int main(int argc, char *argv[]) {
// ... 処理 ...
return 0;
}
int argc
(Argument Count)- プログラムに渡された引数の個数を格納する整数型変数です。
- プログラム名自身も1つと数えられるため、
argc
の値は必ず1以上になります。
char *argv[]
(Argument Vector)- 渡された引数の文字列が格納された配列です。
char *
は文字列を意味し、[]
はそれが配列であることを示します。 argv[0]
には、プログラム名自身が格納されます。argv[1]
には、1番目の引数が格納されます。argv[2]
には、2番目の引数が格納されます。(以下同様)
- 渡された引数の文字列が格納された配列です。
argc
, argv
の中身を見てみよう
実際にコマンドラインから my_program.exe hello c-language
のように引数を渡して実行した場合、argc
と argv
の中身は以下のようになります。
argc
の値:3
argv[0]
:"my_program.exe"
argv[1]
:"hello"
argv[2]
:"c-language"
次のプログラムは、渡された引数をすべて表示します。
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("渡された引数の数 (argc): %d\n", argc);
for (int i = 0; i < argc; i++) {
printf("argv[%d] の値: %s\n", i, argv[i]);
}
return 0;
}
このプログラムをコンパイルして my_app.exe
という名前で保存し、コマンドプロンプトで my_app.exe first second
と実行すると、次のように表示されます。
渡された引数の数 (argc): 3
argv[0] の値: my_app.exe
argv[1] の値: first
argv[2] の値: second
スペースを含む引数を渡したい場合は、" "
(ダブルクォーテーション)で囲みます。 my_app.exe "hello world"
→ argc
は2, argv[1]
は"hello world"
になります。
引数の文字列を数値に変換する
コマンドラインから受け取った引数は、すべて文字列として扱われます。そのため、引数を数値として計算に使いたい場合は、文字列を数値に変換する関数が必要です。
atoi
関数:文字列を整数へ(手軽な方法)
atoi
(ASCII to integer) は、<stdlib.h>
に含まれる関数で、数字の文字列をint
型の整数に変換します。
C
#include <stdio.h>
#include <stdlib.h> // atoi を使うために必要
int main(void) {
char number_string[] = "2025";
int number = atoi(number_string);
printf("文字列 \"%s\" を整数に変換すると %d です。\n", number_string, number);
printf("計算結果: %d\n", number + 1);
return 0;
}
実行結果:
文字列 "2025" を整数に変換すると 2025 です。
計算結果: 2026
strtol
関数:より安全で高機能な変換(推奨)
atoi
は手軽ですが、”abc”のような数字でない文字列が渡された場合に0
を返すだけで、エラーなのか本当に0
なのか区別がつきません。
より安全なプログラムを作るためには、strtol
(string to long) 関数が推奨されます。エラーチェックがより厳密に行えます。
実践例:コマンドライン電卓プログラム
argc
とargv
、そしてatoi
を使って、簡単な足し算を行うコマンドライン電卓を作ってみましょう。 「calculator.exe 123 456
」のように実行すると、その和を計算します。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
// 引数が3個(プログラム名, 数値1, 数値2)でない場合は使い方を表示して終了
if (argc != 3) {
printf("使い方: %s [数値1] [数値2]\n", argv[0]);
printf("例: %s 100 200\n", argv[0]);
return 1; // エラー終了
}
// argv[1] と argv[2] を整数に変換
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
int sum = num1 + num2;
printf("%d + %d = %d\n", num1, num2, sum);
return 0;
}
このプログラムは、まずargc
をチェックして、引数が正しく渡されているかを確認しています。このように、引数の数を最初にチェックするのは、コマンドラインツールを作る際の定石です。
おまけ:数値を書式付きで文字列に変換する sprintf
atoi
とは逆に、数値を特定の書式を持つ文字列に変換したい場合があります。その際に便利なのがsprintf
関数です。printf
と似ていますが、コンソールに出力する代わりに、指定した文字列変数に結果を書き込みます。
sprintf(書き込み先の文字列変数, "書式", 値);
使用例:連番ファイル名を作成する
#include <stdio.h>
int main(void) {
char filename[20];
int file_number = 5;
// "log_005.txt" という文字列を生成する
sprintf(filename, "log_%03d.txt", file_number);
printf("生成されたファイル名: %s\n", filename);
// この後、fopen(filename, "w") のようにしてファイルを作成できる
return 0;
}
実行結果:
生成されたファイル名: log_005.txt
%03d
は「3桁に満たない場合は0で埋める」という書式指定です。このように、コマンドライン引数で受け取った番号を基に、連番のファイル名を生成する、といった応用が可能です。
まとめ
main
関数はint argc
とchar *argv[]
を使ってコマンドライン引数を受け取る。argc
は引数の個数、argv
は引数の文字列配列。argv[0]
はプログラム名。- 引数は全て文字列なので、数値として使うには
atoi
やstrtol
で変換する必要がある。 - プログラムの冒頭で
argc
をチェックし、引数の数が正しいか検証するのが良い習慣。
コマンドライン引数を使いこなせると、プログラムの汎用性が一気に高まります。ぜひマスターして、より柔軟で便利なツールを作成してみてください。