第42回
仕様設計からコーディングまで~タブ/スペース変換プログラムを作る(2)

各処理の説明

各処理を説明していきましょう。なお、完成したソースは"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号の田村 淳が
↓→→
アノ
と発音したのを、他のお笑いタレントたちが

→→→
ピアノ(強調なし)
だよ、と平板な発音に正していたのが印象に残っています。

なんだか、「東京の標準語では平板に発音するのが当たり前だよ」と言われているみたいで、関西人の僕としてはひっかかってしまったのです。

ちなみに、数年前まで関西の技術屋は
   →→↓→→
早よぉコンイルせぇや!
のようにアクセントのある発音をしていました。ところが最近では、関西人でも平板な発音をする人が目立つようになってきました。

アクセントのある発音と平板な発音――どちらが正しいという類のものではないと思います。カタカナ表記になった時点で、その言葉は「日本語」――つまり英語の発音云々とは異なる言葉になったのでしょう。でも、どこか違和感を覚えてしまいます。

関東と関西だけで比較しましたが、それ以外の地方で活躍しているみなさんは、どのような発音をしているのでしょうか?気になります。