太田 晃 [著] 2009/07/23 14:00
このエントリーをはてなブックマークに追加

サンプルファイル 6.00 KB
1 2 3 4 →

 CUIベースのツールを作るとき、面倒な処理としてコマンドラインオプションの解析が挙げられます。本稿では、PC-UNIX系の環境でよく使われるgetopt関数をC言語から使う様子を紹介しながら、同様の方法をWindows上で実現するための方法について説明します。

はじめに

 C#やVB.NETを用いることで手軽にGUIアプリケーションが作れるようになったとはいえ、ちょっとしたツールを書くときなどは、手軽さからC言語を使ったCUIのプログラムにしてしまうことが多いのではないかと思います。このようなCUIベースのツールを作るとき、よく使うのに面倒な処理としてコマンドラインオプション(以下オプション)の解析が挙げられます。

 そこで本稿では、PC-UNIX系の環境でよく使われるgetopt関数をC言語から使う様子を紹介しながら、同様の方法をWindows上で実現するための方法について説明します。

対象読者

  • C言語を理解していて、getopt関数を使ったオプションの解析方法を知りたいという方

 なお、サンプルプログラムはすべてC言語で書かれており、Debian GNU/Linux + gcc 4.3でコンパイルと動作確認を行っています。また、Windows向けに書いたプログラムについては、Windows XP(Professional) SP3 + Visual Studio 2008を用いてコンパイルおよび動作の確認を行っています。

シンプルなオプションの解析

 getoptを使ったオプションの解析方法を見る前に、そもそもオプションの解析とは何をしているのかについて考えていきたいと思います。

 題材として、引数に指定されたファイルから一文字ずつデータを取り出し、標準出力に出力するという単純なプログラムを考えます(リスト1)。

リスト1
/* ファイルの内容を書き出すだけのシンプルなプログラム */
#include <stdio.h>

int main(int argc, char *argv[])
{
	int c;
	FILE *fp;

	if( *++argv ) {
		if( (fp = fopen( *argv, "r" ) ) == NULL ) {
			fprintf( stderr, "Can't opened fle.\n" );
		} else {
			while( ( c = getc(fp) ) != EOF ) {
				putchar(c);
			}
			fclose( fp );
		}
	} else {
		printf( "Usage : command [filename]\n" );
	}
	return 0;
}

 ここで、このプログラムに-nオプションをつけて実行すると、改行記号を無視して表示するように改造したいとしましょう。すると、リスト2に示すような形で、オプションを解析し、必要な処理を行うコードを書くことになります。

リスト2
/* -nオプションが指定されたら、改行を無視するようにしたプログラム */
#include  <stdio.h>
int main(int argc, char *argv[])
{
	int c;
	int flg = 0;
	FILE *fp;

	if( *++argv ) {
		if( !strcmp( *argv, "-n" ) ) {
			flg = 1;
			++argv;
		}

		if( (fp = fopen( *argv, "r" ) ) == NULL ) {
			fprintf( stderr, "Can't opened fle.\n" );
		} else {
			while( ( c = getc(fp) ) != EOF ) {
				if( flg ) {
					if( c != '\n' ) putchar(c);
				} else {
					putchar(c);
				}
			}
			putchar('\n');
			fclose( fp );
		}

	} else {
		printf( "Usage : command [filename]\n" );
	}	
	
	return 0;
}

 ご覧いただけば分かるとおり、オプションの解析というのは、突き詰めていけば

  • オプションとなる引数があるのか?
  • ある場合、それは正しい引数か?

 などをチェックし、それに応じてフラグを起こしたり、メッセージの表示処理をするというのが主体になります。基本的には、getoptなどのオプション解析機能を使った場合に、その中で行われている操作もこれと同じです。であれば、コードは汚くなりますが、この調子でifによる分岐を増やしていけば、getoptなどを使うまでもなく、5個や6個の機能拡張であれば簡単に行えそうな気がします。

 しかし、オプションがさらに引数をとる必要性が出てきたり、あるオプションの引数が省略可能だったり、オプションの指定される順序が決まっていない場合を考えるとどうでしょう? 想像するだけで面倒な感じがします。けれどもgetoptを使えば、そういった面倒な要求にもきちんと答えてくれるオプションの解析が可能なのです。


1 2 3 4
→
INDEX
C言語を使ったコンソールアプリケーションの作成 コマンドラインオプションの解析方法
Page1
はじめに
対象読者
シンプルなオプションの解析
getoptを使って書き直す
getoptを使ったプログラムでよく見られるテクニック
より複雑なオプションを、getoptを用いて解析する
Windows環境でオプションを解析する
まとめ
参考資料
こちらの関連記事もおすすめです

プロフィール
太田 晃 オオタ アキラ

 ブログ(http://repse.blogspot.com/)では、coLinux上にMinGWを用いてクロスコンパイル環境を構築し、そのうえでSDLやOpenGLを使ってWindows向けのプログラムを書くとか、海外のソフトウェアを(勝手に)日本語化するとか、Windowsのインデックスサービスを叩いてみるとか、あんまり人がやらないことを、こっそり・ひっそりやってます。


記事へのコメント・トラックバック機能は2011年6月に廃止させていただきました。記事に対する反響はTwitterやFacebook、ソーシャルブックマークサービスのコメントなどでぜひお寄せください。