オールFFファイル(その2)

今回もアニメを見てません。勤勉にゲームしてます。タイトルから推測するに、きっとファイナルファンタジーではないのか、と思うかもですが、マイクラです。
そして今回も、タイトルはオールFFファイルなのに、作るプログラムが全然オールFFではないです。次回あたりにFFになると思います。

前回作ったプログラムの最後の形がこれでした。今回はこれをベースにgetoptを使用してのオプション解析ができるように改造します。

takk@deb9:~/tmp$ cat -n t.c
     1	#include <stdio.h>
     2	#include <stdlib.h>
     3	
     4	int main(int argc, char* argv[])
     5	{
     6		FILE *fp;
     7		int size;
     8	
     9		if(argc != 3){
    10			printf("parameter error\n");
    11			return 1;
    12		}
    13		size = atoi(argv[2]);
    14		fp = fopen(argv[1],"w");
    15	
    16		while(size--)
    17			fputc(0,fp);	
    18	
    19		fclose(fp);
    20	}
    21	
takk@deb9:~/tmp$ 

このプログラムに、オプション解析してくれるgetoptを組み込みます。getoptは、型が思い出せないのでマニュアルを読みます。manコマンドでよいのですが、知りたいのは、getoptコマンドではなく、ライブラリ関数のgetoptなので、
ライブラリの番号3を指定してman実行します。

takk@deb9:~/tmp$ man 3 getopt
GETOPT(3)        Linux Programmer's Manual       GETOPT(3)

名前
       getopt,   getopt_long,   getopt_long_only,  optarg,
       optind, opterr, optopt - コマンドラインオプションを
       解釈する

書式
       #include <unistd.h>

       int getopt(int argc, char * const argv[],
                  const char *optstring);


(省略)

manの表示はまだまだ下に続きますが,型が分かれば十分です。

では改造。インクルードから。

     1	#include <stdio.h>
     2	#include <stdlib.h>
     3	#include <unistd.h>

getoptを使うために、unistd.hを追加。

     4	
     5	int main(int argc, char* argv[])
     6	{
     7		FILE *fp;
     8		int size = 0;
     9		int ch;
    10	

コマンドをswitchでチェックするので、文字変数としてint chを定義。

    11		while ((ch = getopt(argc, argv, "s:")) != -1){
    12			switch (ch) {
    13			case 's':   
    14				size = atoi(optarg);
    15				break;
    16			default:
    17				printf("parameter error\n");
    18				return 1;
    19			}
    20		}
    21	

while文の中で、getoptを使います。”s:”とすると、sオプション、かつ引数ありとなります。case ‘s’の場合に、optargを使っていますが、sで指定した数字(文字列)が格納されています。指定したオプションが -s以外なら、deafult処理として、パラメータエラーを表示するようにしています。

    22		if(optind >= argc){
    23			printf("parameter error\n");
    24			return 1;
    25		}
    26	

オプション解析が終わったら、パラメータ数のチェックをします。オプションに加えて、ファイル名も必要なので、不足があればパラメータエラーとしています。

    27		fp = fopen(argv[optind],"w");

最後に、optindがファイル名が格納されているargvのインデックスとなるので、これを使用してファイル名を取得します。

全ソースです。

takk@deb9:~/tmp$ cat -n t.c
     1	#include <stdio.h>
     2	#include <stdlib.h>
     3	#include <unistd.h>
     4	
     5	int main(int argc, char* argv[])
     6	{
     7		FILE *fp;
     8		int size=0;
     9		int ch;
    10	
    11		while ((ch = getopt(argc, argv, "s:")) != -1){
    12			switch (ch) {
    13			case 's':   
    14				size = atoi(optarg);
    15				break;
    16			default:
    17				printf("parameter error\n");
    18				return 1;
    19			}
    20		}
    21	
    22		if(optind >= argc){
    23			printf("parameter error\n");
    24			return 1;
    25		}
    26	
    27		fp = fopen(argv[optind],"w");
    28	
    29		while(size--)
    30			fputc(0,fp);	
    31	
    32		fclose(fp);
    33	}
    34	
takk@deb9:~/tmp$ 

実行結果です。

takk@deb9:~/tmp$ gcc t.c
takk@deb9:~/tmp$ ./a.out
parameter error
takk@deb9:~/tmp$ ./a.out aaa.bin
takk@deb9:~/tmp$ od -tx1 -Ad aaa.bin
0000000
takk@deb9:~/tmp$ ./a.out -s10
parameter error
takk@deb9:~/tmp$ ./a.out -s10 bbb.bin
takk@deb9:~/tmp$ od -tx1 -Ad bbb.bin
0000000 00 00 00 00 00 00 00 00 00 00
0000010
takk@deb9:~/tmp$ 

コメント

タイトルとURLをコピーしました