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の値:3argv[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をチェックし、引数の数が正しいか検証するのが良い習慣。
コマンドライン引数を使いこなせると、プログラムの汎用性が一気に高まります。ぜひマスターして、より柔軟で便利なツールを作成してみてください。
