4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[初学者向け] C言語 argc, argvとはなんぞや

Last updated at Posted at 2023-01-04

argc, argv (c言語のメイン関数がとるコマンドライン引数) の勉強のために書いてみました.
僕と同じ初学者の方で, argc, argvとはなんぞやという人のお役に立てばと思います.
環境としては、macでVSコード(Visual Studio Code)中心に使っていて, TerminalかiTermを使うこともあります.
プログラミング自体がはじめての方, 「コマンドライン, 引数って何?」という方はよかったらこちらをご覧ください.


1. argc, argvとは

1-1. [argc]

"argument count"の略で, 入力したコマンドライン引数の個数をコンピューターが自動的に数えてくれたものです.
プログラム実行コマンド(デフォルトでは"./a.out")もコマンドライン引数としてカウントされます.

コマンドライン
 % ./a.out

プログラム実行時, コマンドラインにプログラム実行コマンド("./a.out")以外の引数を入力しなければ, 引数は実行コマンドのみになるため, 引数の個数は1つだけとなります. そのため, 上のコマンドラインから計測されるargcの値は1になります.

ただし, カウントされるのはプログラム実行コマンドとその後の入力値のみのようです.
例えば以下のようなコマンドを入力した場合, 上の"user % ./a.out"と同じでargcは1となります.

コマンドライン
 % gcc -Wall -Wextra -Werror command_line_args.c ; time ./a.out

(プログラムのメイン関数が認識するコマンドライン引数は"./a.out"のみ. コマンドライン上の他の引数 ("gcc"から"time"まで) はメイン関数への引数としてはカウントされない)

1-2. [argv]

"argument vector"の略で, 入力したコマンドライン引数の入力値(文字)を指します.
argv[0]は実行したプログラム名(デフォルトでは"./a.out").
プログラムファイル名の後に入力した値(文字)がargv[1]以降のコマンドライン引数として扱われます.

コマンドライン
 % ./a.out string 12345

↑ この場合, "string" -> argv[1], "12345" -> argv[2] になる. argcは3.

2. コーディング -> プログラム実行

2-1. ファイル作成 (詳細はここをクリック)
コマンドライン
 % touch args.c

2-2. コーディング

エディタ
    #include <stdio.h>

    int	main(int argc, char *argv[])
    {
    	printf("argc    = %d\n", argc);
    	printf("argv[0] = %s\n", argv[0]);
    	printf("argv[1] = %s\n", argv[1]);
    	return (0);
    }
2-3. コンパイル (詳細はここをクリック)
コマンドライン
 % gcc -Wall -Wextra -Werror args.c

プログラミング自体がはじめて, 「ファイル作成 -> コンパイル -> プログラム実行をまだやったことない!」 という方は, よかったらこちらをご覧ください.

https://qiita.com/uzo/items/e739340a9a120a50b55d

2-4. プログラム実行

コマンドライン
 % ./a.out

2-5. 実行結果

無事プログラムが実行されると, 以下のように出力されるはずです.

ターミナル
       argc    = 1    
       argv[0] = ./a.out
       argv[1] = (null)

上記の"% ./a.out"のプログラム実行コマンドラインでは, "./a.out"以外に何も入力してないので, コマンドライン引数は"./a.out"だけとなります.

そのため, コマンドライン引数の個数は1つだけです. ということで, "argc"は1になり, "./a.out"は最初のコマンドライン引数ということで, "argv[0]"となります.

今回のコードでは"argv[1]"もprintf()関数で出力するようにしてますが, 上のコマンドラインでは”./a.out”の後に何も入力されてません.
そのためargv[1]は入力なしということで, "(null)"(ナル: 無効)と出力されてます.

3. コマンドライン引数を追加

3-1. argv[1] = "string"

では, 今度はコマンドライン引数を追加で入力してみましょう.
文字列を意味する"string"を"./a.out"の後ろに半角スペースを置いたあとに入力してみます.
コマンドライン引数はそれぞれ半角スペースで区切られていることで認識されます.

コマンドライン
 % ./a.out string

最初に載せたコードを使ってコンパイルすると, 結果は以下のようになるはずです.

ターミナル
       argc    = 2
       argv[0] = ./a.out
       argv[1] = string

今回のコマンドライン引数は"./a.out"と"string"ですから, コマンドライン引数は2つ. そのため, "argc"は2となり, "argv[0]"はさっきと同じ "./a.out". さっきは入力なしで, printf()関数では"(null)"として出力されていた"argv[1]"の値は, 今度は"string"となって出力されました.

3-2. argv[2] = "12345"

ではこんなのはどうでしょうか

コマンドライン
 % ./a.out string 12345

今度は "./a.out" (スペース) "string" (スペース) "12345"という入力内容です. 結果は以下のようになるはずです.

ターミナル
       argc    = 3 
       argv[0] = ./a.out
       argv[1] = string

3つめのコマンドライン引数"12345"は"argv[2]"として認識されているのですが, "argv[2] = 12345"のように出力されてはいません. これは, 最初に載せたコード内でprintf()関数が出力するように指定したargv[]が, argv[1]までだからです. ただ, 出力はされてないですが、認識はされてるので、"argc"の値は3となってます.

"argv[1]"以降のコマンドライン引数をプリントしたい場合,

    printf("argv[1] = %s\n", argv[1]);

の関数をコピペして, "argv[1]"のところの数字を2, 3と変えてあげれば, 他のコマンドライン引数も出力できます.

4. スペースも引数の一部として入力したい

また、コマンドライン引数はスペースで区切られると上に書きましたが, スペースも文字列の一部として入力したい場合はスペースを含んだ文字列を" " (ダブルクォーテーション)で囲んであげましょう.

先ほどの

コマンドライン
 % ./a.out string 12345

コマンドライン
 % ./a.out "string 12345"

としてみてください. 結果は以下のようになるはずです.

ターミナル
    argc    = 2
    argv[0] = ./a.out
    argv[1] = string 12345

5. 安全なコーディングのために

また, コメントで指摘をいただいたので, より安全にプログラムを実行するために下記のようなコードを書いてみました.

#include <stdio.h>

int	main(int argc, char *argv[])
{
	int	i;

	i = 0;
	printf("argc    = %d\n", argc);
	while (i < argc)
	{
		printf("argv[%d] = %s\n", i, argv[i]);
		i++;//または i += 1;
	}
	return (0);
}

こうすると, 入力されたコマンドライン引数をすべて出力しつつ, 引数の数を超えてprintf()関数がargvを出力しようとするのを防げます.
先ほどの

コマンドライン
 % ./a.out string 12345

をコンパイル後に実行すると, 結果は以下のようになるはずです.

ターミナル
    argc    = 3
    argv[0] = ./a.out
    argv[1] = string
    argv[2] = 12345
4
6
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?