with-open-fileをC++/C99で

Common Lispにはwith-open-fileというマクロがあります。

(with-open-file (stream filename)
  ...
  (read-line s)
 ...
 )

このマクロは、ファイルをオープンして、
ここを抜けるときに自動的にファイルをクローズしてくれるというものです。
そのため、ファイルの閉じ忘れがおこりません。

このマクロをC++、もしくはC99で再現する方法を思いついたのでメモしておきます。

#define with_open_file(s,p,m) \
  for(FILE *s=fopen(p,m); s; fclose(s),s=NULL)
...
void hoge(char *path) {
  char buf[256];
  with_open_file(fp, path, "r") {
    ...
    fgets(buf, sizeof(buf), fp);
    ...
  }
}

短いコードでなかなかいい感じだと思います。
残念ながら、本物のwith-open-fileと異なり、returnなどで関数を抜けたときに、
ファイルを閉じてくれないという問題がありますが。
(その他にも、breakやcontinueを中で使ったらまずいとか、色々あるけど、
まあ、一発ネタなんで、深いことは考えないことにします。)

5 Responses to “with-open-fileをC++/C99で”

  1. alohakun より:

    C++ なら普通にデストラクタ使えば…

  2. zick より:

    それは内緒です。
    C99でも動くという言い訳でお許しください。

  3. たけおか より:

    return や longjmp()できないと、まったく、全然、完璧かつ完膚なきまでに無意味不明だよ。

  4. zick より:

    あくまでも、思いつきの一発ネタなので。

  5. 127 より:

    読み込み処理でループ処理でヘッダが無い場合なら、ループを二重にして
    for(FILE *s=fopen(p,m);s;fclose(s),s=NULL)for(;!feof(s);)
    としておけばbreakとcontinueは使えるようになりますね。
    だがこの方法で先の条件を緩和しようとするとfcloseが二回になるとかフラグ変数が増えるとかで綺麗じゃないし、やはり一発ネタか・・・

    return制約はアレだけど、longjmp出来ないと駄目とか・・・longjmpってポインタやgoto以上に泥臭いCの暗黒面だと思うんだけど。
    言語機能を拡張する時とかリソース制約上仕方なく使うことはあっても、まともな感性持った人が日常で使う機能では無い様な。

Leave a Reply