fmemopen

Autres langues

Langue: ja

Version: 2005-12-08 (fedora - 25/11/07)

Section: 3 (Bibliothèques de fonctions)

名前

fmemopen, open_memstream - メモリをストリームとしてオープンする

書式

#define _GNU_SOURCE
#include <stdio.h>

FILE *fmemopen(void *buf, size_t size, const char *mode);

FILE *open_memstream(char **ptr, size_t *sizeloc)

説明

fmemopen() 関数は、ストリームをオープンし、そのストリームに mode で指定されたアクセス許可を設定する。 そのストリームは、 buf で指定された文字列、つまりメモリバッファとして読み書きできる。 このバッファは少なくとも size バイトの長さでなければならない。

引き数 modefopen(3) の場合と同じである。 mode で追記モード (append mode) が指定された場合、ファイル位置の初期値は バッファ中の最初の NULL バイト ('\0') の位置に設定される。 それ以外の場合は、ファイル位置の初期値はバッファの先頭になる。

書き込み用にオープンされたストリームをフラッシュ (fflush(3)) やクローズ (fclose(3)) した時に、 (バッファに空きがあれば) NULL バイトがバッファの末尾に書き込まれる。 このようにするためには、呼び出し元は バッファに 1バイト余裕を作る (size にこの 1バイトを含めた値を指定する) 必要がある。

バッファに size バイトよりたくさん書き込もうとした場合には、エラーとなる。 (デフォルトでは、このようなエラーは stdio バッファがフラッシュされた時にしか見えない。 setbuf(fp, NULL) を使ってバッファリングを無効にする方法は、 出力操作を行ったときにエラーを検出するのに役立つ。 別の方法としては、 setbuffer(fp, buf, size) を使って、呼び出し側が明示的に stdio ストリームバッファとして buf を指定し、バッファの指定時にバッファのサイズを stdio に教える方法がある。)

読み出し用にオープンされたストリームでは、 バッファ内に NULL バイト ('\0') があっても 読み出し操作がファイル末尾 (end-of-file) を返すことはない。 バッファからの読み出しでファイル末尾が返るのは、 ファイルポインタがバッファの先頭から size バイトを越えて先に進もうとした場合だけである。

buf に NULL が指定された場合、 fmemopen() は動的に size バイトの長さのバッファを確保する。 この方法は、一時バッファにデータの書き込みを行ってから、 その内容を再度読み出すようなアプリケーションで有用である。 このバッファはストリームがクローズされるときに自動的に解放される。 呼び出し元からはこの関数が割り当てた一時バッファへのポインタ値を 知る方法は存在しない点に注意 (下記の open_memstream() も参照)。

open_memstream() は、バッファへの書き込み用にストリームをオープンする。 バッファは (malloc(3) を使って) 動的に割り当てられ、必要に応じて自動的に伸長する。 ストリームをクローズした後で、読み出し元はこのバッファを free(3) すべきである。

このストリームが クローズ (fclose(3)) されたりフラッシュ (fflush(3)) された時に、 ptrsizeloc の値はそれぞれバッファへのポインタとそのサイズに更新される。 これらの値は、呼び出し元がそのストリームに新たな書き込みを 行わない場合に限り有効である。 ストリームに書き込みを行った際には、これらの変数を参照する前に ストリームを再度フラッシュしなければならない。

バッファ末尾の NULL バイトは保持される。 この NULL バイトは sizeloc に格納されるサイズには「含まれない」。

返り値

成功して終了した場合には、 fmemopen() と open_memstream() は FILE ポインタを返す。 失敗した場合は、 NULL を返し、大域変数 errno にエラーを示す値をセットする。

準拠

これらの関数は GNU 拡張である。

このプログラムは fmemopen() を使って出力バッファをオープンし、 open_memstream() を使って動的にサイズが変化する出力バッファをオープンしている。 (プログラムの第一コマンドライン引き数から取った) 入力文字列を スキャンして整数を読み込み、これらの整数の二乗を出力バッファに書き出す。 このプログラムの実行例は以下のようになる。
 
 $ ./a.out "1 23 43"
 size=11; ptr=1 529 1849
 
 #define _GNU_SOURCE
 #include <assert.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
 
 int
 main(int argc, char *argv[])
 {
     FILE *out, *in;
     int v, s;
     size_t size;
     char *ptr;
 
     assert(argc == 2);
 
     in = fmemopen(argv[1], strlen(argv[1]), "r");
     if (in == NULL)
         die("fmemopen");
 
     out = open_memstream(&ptr, &size);
     if (out == NULL)
         die("fmemopen");
 
     for (;;) {
         s = fscanf(in, "%d", &v);
         if (s <= 0)
             break;
 
         s = fprintf(out, "%d ", v * v);
         if (s == -1)
             die("fprintf");
     }
     fclose(in);
     fclose(out);
     printf("size=%ld; ptr=%s\n", (long) size, ptr);
     free(ptr);
     exit(EXIT_SUCCESS);
 }
 

関連項目

fopen(3), feature_test_macros(7)