Windows programmings (5) - 引数のある光景 - 2001.January
1. 概要
ここしばらくはWin32コンソールなプログラムです。どうしてかと言うと、
しばしば目的達成への最短距離だからです。
用途によるけど、マウスでぺちぺちするのは、非効率以外の何物でもないことが
まま、あります。
例えばdos窓でdel *.txtってやると一瞬だけど、マウス使って同様のことを
したいですか?
一つ一つ*.txtであることを確かめながらマウスで選択してShift + Delする……?
(表示->詳細、ファイルの種類でソートさせて……でも結構手間ですな)
…な、ことをするぐらいならDOS窓開いた方が余程手っ取り早いですよね?
(うちの場合、Tabでパスが補完されるShell使ってるんでcdも簡単だし)
Macのフリーウェアだかシェアウェアだかに、「複数ファイルを一気にリネーム
できます」なんてアプリがあるけど、Windows系だとdos窓でren *.a *.b
すれば終わり。GUIしかないOSだと余計な苦労をする。という良い例ですな。
#Mac OS Xは基本がunixなので、そうではなくなってる。ま、従来のMacユーザが
コマンドラインをどれだけ愛するようになるかは未知数だけど
Windows系って、コマンドラインというかDOS窓というかコンソールって、
冷遇されてますが、Mac系よりはまし。
#GUI系とCUI(コンソール)系のどちらも優遇している、バランスの取れたOS。
ということならunix系ですがね(私見)
それはともかく。Windows MEでもDOS窓はあるんだし(某EPSONマシンで確認済み)、
WinNT/2000でもコンソールはある(レジストリをいじるとtabとかでパスの補完を
やってくれるようになるので便利)。
ということで「コンソールは永遠に不滅です!」(元ネタにピンと来た人は、あたし
同様古い人でしょう[^^;;]←だけど、あたしゃプロ野球って、録画時間を狂わす
元凶としか思ってません。何度*スポンサーの好意*で煮え湯を飲まされたことか。
映画を見るつもりでVTRを起動したら、野球やってる。ってのはとっても悲しい)
……CUIなアプリをGUI化すると2倍以上の手間が掛かると私は思います。
GUIなアプリをCUI化。ってのは無理なこともあると思います。が、CUIで済むなら
わざわざGUIにする必要はないです。
ちゅうことで、Win32コンソールなプログラムです。
ちなみにWindowsでは冷遇されている。というのは、例えば32 bitプログラムでは
ANSIエスケープシーケンスのサポートがない。とか、コマンドラインシェルの
機能が話にならない程貧弱とかいうのを指してますです。
2. オプションとファイル名を1つだけ受け取る例
こんなもんは誰が書いても同じようなもんになる訳ですが、一応、例として。
仕様:
- 引数がない場合は簡単なヘルプ(usage)を出す
- オプションは'-'で指定する。DOS的には'/'だけどさ
- 指定の順番はどうでもよい
- ファイル名は'"'で囲むことでロングファイル名もOK。この辺がWindowsらしさ
#あれ?argvの中身とか書き換えて良かったんだっけ?多分OKのはずだが……
/*
args.c - arguments
*/
#include <stdio.h>
#include <string.h>
int setfilename(char** fn, char* fnbuf)
{
if (*fn!=NULL){
puts("Error: do not specify filename twice!");
return 0;
}
*fn = fnbuf;
return 1;
}
int main(int argc, char* argv[])
{
int i, len;
char *filename=NULL;
if (argc<=1){
printf("Usage: %s [-a][-b] {filename}\n", argv[0]);
return 1;
}
for (i=1; i<argc; i++){
switch (argv[i][0]){
case '-': // switch character
switch (argv[i][1]){
case 'a':
puts("Option A");
break;
case 'b':
puts("Option B");
break;
default:
printf("Error: Invalid option %c\n", argv[i][1]);
return 1;
}
break;
case '"': // string
len = strlen(argv[i]);
if (argv[i][len-1] != '"'){
puts("Error: \" expected.");
return 1;
}
argv[i][len-1] = '\0';
if (!setfilename(&filename, &argv[i][1])) return 1;
break;
default:
if (!setfilename(&filename, &argv[i][0])) return 1;
}
}
printf("Filename: %s", filename);
return 0;
}
(EOF)