FMEMOPEN(3) | Linux Programmer's Manual | FMEMOPEN(3) |
名前
fmemopen, open_memstream, open_wmemstream -メモリをストリームとしてオープンする書式
#include <stdio.h>
FILE *fmemopen(void *buf, size_t size, const char *mode);
FILE *open_memstream(char **ptr, size_t *sizeloc);
#include <wchar.h>
FILE *open_wmemstream(wchar_t **ptr, size_t *sizeloc);
glibc 向けの機能検査マクロの要件 ( feature_test_macros(7) 参照):
fmemopen(), open_memstream(), open_wmemstream():
- glibc 2.10 以降:
- _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
- glibc 2.10 より前:
- _GNU_SOURCE
説明
fmemopen() 関数は、ストリームをオープンし、そのストリームに mode で指定されたアクセス許可を設定する。そのストリームを通じて、 buf で指定された文字列やメモリバッファへの読み書きができる。このバッファは少なくとも size バイトの長さでなければならない。引き数 mode は fopen(3) の場合と同じである。 mode で追記モード (append mode) が指定された場合、ファイル位置の初期値はバッファ中の最初の NULL バイト ('\0') の位置に設定される。それ以外の場合は、ファイル位置の初期値はバッファの先頭になる。 glibc 2.9 以降では、文字'b'を mode の二番目の文字として指定することができる。この文字は「バイナリ」モードを指定するものである。このモードでは、書き込み時に文字列終端のヌルバイトが黙って追加されることはない。また、 fseek(3) SEEK_END は、文字列の長さからの相対値ではなく、バッファの末尾 ( size で指定した値) からの相対値となる。
書き込み用にオープンされたストリームをフラッシュ ( 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)) された時に、 ptr と sizeloc の値はそれぞれバッファへのポインタとそのサイズに更新される。これらの値は、呼び出し元がそのストリームに新たな書き込みを行わない場合に限り有効である。ストリームに書き込みを行った際には、これらの変数を参照する前にストリームを再度フラッシュしなければならない。
バッファ末尾の NULL バイトは保持される。この NULL バイトは sizeloc に格納されるサイズには「含まれない」。
ストリームのファイル位置は fseek(3) や fseeko(3) で変更できる。すでにデータが書き込まれた領域の末尾より先にファイル位置を動かすと、その間の領域は 0 で埋められる。
open_wmemstream() は open_memstream() と同様だが、バイトではなくワイド文字に対して操作を行う点が異なる。
返り値
成功して終了した場合には、 fmemopen(), open_memstream(), open_wmemstream() は FILE ポインタを返す。失敗した場合は、 NULL を返し、 errno にエラーを示す値をセットする。バージョン
fmemopen() と open_memstream() は glibc 1.0.x ですでに利用可能であった。 open_wmemstream() は glibc 2.4 以降で利用可能である。準拠
POSIX.1-2008. これらの関数は POSIX.1-2001 では規定れていないが、 Linux 以外のシステムで広く利用可能である。注意
これらの関数が返すファイルストリームに対応するファイルディスクリプタはない (つまり、返されたストリームに対して fileno(3) を呼び出すとエラーが返ることになる)。バグ
バージョン 2.7 より前の glibc では、 open_memstream() で作成されたストリームの末尾より先にファイル位置を動かしても、バッファが伸長されず、 fseek(3) が失敗し-1 が返る。例
このプログラムは fmemopen() を使って出力バッファをオープンし、 open_memstream() を使って動的にサイズが変化する出力バッファをオープンしている。 (プログラムの第一コマンドライン引き数から取った) 入力文字列をスキャンして整数を読み込み、これらの整数の二乗を出力バッファに書き出す。このプログラムの実行例は以下のようになる。
$ ./a.out '1 23 43'
size=11; ptr=1 529 1849
プログラムのソース
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define handle_error(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;
if (argc != 2) {
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
exit(EXIT_FAILURE);
}
in = fmemopen(argv[1], strlen(argv[1]), "r");
if (in == NULL)
handle_error("fmemopen");
out = open_memstream(&ptr, &size);
if (out == NULL)
handle_error("open_memstream");
for (;;) {
s = fscanf(in, "%d", &v);
if (s <= 0)
break;
s = fprintf(out, "%d ", v * v);
if (s == -1)
handle_error("fprintf");
}
fclose(in);
fclose(out);
printf("size=%ld; ptr=%s\n", (long) size, ptr);
free(ptr);
exit(EXIT_SUCCESS);
}
関連項目
fopen(3), fopencookie(3)この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2012-04-28 | GNU |