各処理の説明
各処理を説明していきましょう。なお、完成したソースは"ex4202.c"、DOS版の実行形式ファイルは"ex0402.exe"という名前でサンプルに収録しています。
構造体の定義(リスト2)
構造体の定義箇所では、単にタブストップ幅とファイル名だけではなく、fopen関数でファイルをオープンした場合に返ってくるファイルポインタ(FILE構造体へのポインタ)も保存できるようにしています。
このようにしておけば、後に複数のファイルに対応できるよう改良した場合に、複数のファイルをまとめてオープンし、ファイルポインタがNULL(オープンエラー)でないファイルだけを連続して読み込む――といった処理も可能になります。
typedef struct {
int tab;
char *fname;
↓オープンしたファイルのファイルポインタ
FILE *fp;
} TabConv;
パラメータを構造体に格納する(リスト3)
setdata関数はmain関数から呼び出されます。main関数の側で、コマンドライン・パラメータのタブストップ幅とファイル名を予めTabConv型の構造体にセットしておき、その構造体へのポインタを引数として受け取って、ファイルを「読み出しモード」でオープンします。
int setdata(TabConv *p)
{
↓タブストップ幅が最小値未満なら標準値へ
if (p->tab < MIN_TAB)
p->tab = DEFAULT_TAB;
↓タブストップ幅が最大値より大きければ最大値へ
else if (p->tab > MAX_TAB)
p->tab = MAX_TAB;
↓ファイルをオープンして成功すればTRUE、失敗ならFALSEを返す
if ((p->fp = fopen(p->fname, "r")) == NULL) {
fprintf(stderr, "%s がオープンできません.¥n", p->fname);
return (FALSE);
}
return (TRUE);
}
パラメータのチェック(リスト4)
argchk関数もmain関数から呼び出され、コマンドライン・パラメータの数を調べます。パラメータが最小数(タブストップ幅とファイル名の2個)より少なければエラーメッセージを表示してFALSEを返し、それ以外はTRUEを返します。
main関数でFALSEを受け取るとエラーでプログラムを終了し、呼び出した上位プログラム(主にシェル)へエラーコード(-1)を返します。
先のex4201.cでは、この処理の中でエラーがあればexitでプログラムを終了させていましたが、それはこの処理自体がmain関数の中にあったためです。ここではmain関数から呼び出される別の関数としたため、エラーの場合はFALSE、成功すればTRUEをmain関数に返すという仕様に変更しています。
int argchk(int argc)
{
if (argc < ARGMIN) {
fputs("TABCONV : タブストップ幅(1-16)とファイル名を指定してください.",
stderr);
↓コマンドライン・パラメータが足りなければFALSEを返す
return (FALSE);
}
↓コマンドライン・パラメータに問題がなければTRUEを返す
return (TRUE);
}
main関数の流れ
main関数は、以下のような動作をしています。
(1) TabConv型の構造体を生成する
(2) 生成した構造体をポインタで扱えるようにする
(3) argchk関数を呼び出してコマンドライン・パラメータをチェックする
間違っていればエラーで終了する
(4) コマンドライン・パラメータのタブストップ幅とファイル名をTabConv型構造体のメンバに
設定(代入)する
(5) setdata関数を呼び出して入力ファイルをオープンする
オープンエラーならメッセージを表示して終了する
(6) whileループの中でtb2sp関数を呼び出してタブをスペースに変換する
int main(int argc, char *argv[])
{
char rbuf[BUFSIZE + 1]; /* 読み込みバッファ */
char wbuf[BUFSIZE + 1]; /* 書き出しバッファ */
TabConv indata, *p; /* TabConv型の変数を定義 */ -------- (1)
p = &indata; /* ポインタを初期化し、構造体のデータを --- (2)
ポインタで扱えるようにする */
if (argdhk(argc) == FALSE) ------------------------------------ (3)
exit(ERR);
p->tab = atoi(argv[1]); /* オプション文字を数値に直す */ --- (4)
p->fname = argv[2];
if (setdata(p) == FALSE) -------------------------------------- (5)
exit(ERR);
fprintf(stderr, "タブストップ間隔 : %d¥n", p->tab);
while (fgets(rbuf, BUFSIZE, p->fp) != NULL) { ----------------- (6)
tb2sp(rbuf, wbuf, p->tab);
fputs(wbuf, stdout);
}
fprintf(stderr, "¥a¥t---- 変換終了しました!!¥n");
}
サンプルのプログラムについて
今回のサンプルにも、タブ→スペースの変換を試すために"test.txt"というタブコードを使ったCのソースファイルを添付しています。
内容は、前回の同名のファイルと同じです。これをコンパイルしてもエラーが出ますので、注意してください。
今回紹介したプログラムのソースファイルは"ex4201.c"と"ex4202.c"の2つです。
【サンプルファイル実行の注意点】
お使いのOSによっては日本語の部分が文字化けする可能性がありますが、再コンパイルすることで回避できます。
あとがき
hiropの『ちょっと気になる専門用語』~《平板な発音》
アクセントあり? なし?
ここ数年、会話の中で「コンパイル」「コンパイラ」の発音が気になっています。
どちらも「パ」にアクセントがあり、かつては誰もがそのように発音していたのですが、最近はどこにもアクセントを置かない『平板な発音』を聞くことが多くなりました。
「リンク」「リンカ」も同じで、以前は「リ」にアクセントがあったのですが、これも最近では平板な発音が目立ちます。
文字では伝わりにくいですね。→を平板、↓を強い音(アクセント)とすれば以下のような感じです。
→→↓→→
これまで:コンパイラは何を使ってますか?
→→→→→
最近 :コンパイラは何を使ってますか?
↓→→
これまで:ここでリンクするんですね。
→→→
最近 :ここでリンクするんですね。
マスコミから技術屋へ伝染?!
これは、「グラス」「ピアノ」「クラブ」などのような平板読みが、開発者の世界にも浸透してきたことの表れだと思います。元々は、関東地方でもそれぞれ「グ」「ピ」「ク」のように先頭にアクセントがあったのですが、1990年代に入った頃からでしょうか、どこにもアクセントを付けない平板読みが、マスコミ――特にテレビから始まって出版の世界へと広まっていきました。
我々技術屋はそんな風潮とは無関係に、日本語カタカナ表記の発音も英語の発音を基本としていました。ところが、技術雑誌の編集者と話していて、「あれっ、なんかアクセントの位置が違う……」と思うようになったのが1990年代の中頃です。
※ 英語の発音では、「ピアノ」は「ア」にアクセントがあります
関西でも広がる「平板読み」
まぁ、どちらでもいいと言えばそうなのですが、お正月に放送されたテレビのバラエティ番組で、元々は関西弁だったロンドンブーツ1号2号の田村 淳が
↓→→
ピアノ
と発音したのを、他のお笑いタレントたちが
→→→
ピアノ(強調なし)
だよ、と平板な発音に正していたのが印象に残っています。
なんだか、「東京の標準語では平板に発音するのが当たり前だよ」と言われているみたいで、関西人の僕としてはひっかかってしまったのです。
ちなみに、数年前まで関西の技術屋は
→→↓→→
早よぉコンパイルせぇや!
のようにアクセントのある発音をしていました。ところが最近では、関西人でも平板な発音をする人が目立つようになってきました。
アクセントのある発音と平板な発音――どちらが正しいという類のものではないと思います。カタカナ表記になった時点で、その言葉は「日本語」――つまり英語の発音云々とは異なる言葉になったのでしょう。でも、どこか違和感を覚えてしまいます。
関東と関西だけで比較しましたが、それ以外の地方で活躍しているみなさんは、どのような発音をしているのでしょうか?気になります。
|
|
|