GFS_PIO_READDELIM(3)

NAME
gfs_pio_readdelim - 一レコード読み込み

SYNOPSIS

#include <gfarm/gfarm.h>

char *gfs_pio_readdelim (GFS_File f, char **bufp, size_t *sizep, size_t *lenp, char *delimiter, size_t delimlen);

DESCRIPTION

この関数は、gfs_pio_readline(3) と同様に働きますが、ただし、 入力のセパレータを改行文字に限らず、一般的に指定できるように したものです。 この関数は、ファイル gf から、 引数 delimiter で指定されたバイト列をレコード間区切りとして、1レコード読みとり ます。 引数 delimiter には文字 '\0' を含むこともできます。このため、区切りの長さを 引数 delimlen で指定します。 なお、 引数 delimiter が NULL の場合、ファイル全体を1レコードとしてメモリ上に読み込みます。 そうではなく、かつ 引数 delimlen が 0 の場合、一個以上の連続する空行 (正規表現では /\n\n+/) を レコード区切りと見なします。この仕様は perl 言語の INPUT_RECORD_SEPARATOR を参考にしています。

引数 bufp は、最初は NULL で初期化されたポインタ変数のアドレスを指定します。 関数 gfs_pio_readdelim() は、入出力に用いる バッファを動的に割り当て、そのアドレスをこのポインタ変数に記録します。 引数 sizep は、0 で初期化した size_t 型の変数 のアドレスを指定します。この変数は、バッファのサイズを記録するために 使われます。 あるいは、malloc(3) で割り当てたバッファを指すポインタのアドレスを 引数 bufp に指定することもできます。この場合、 引数 sizep は、割り当てたバッファのサイズで初期化しておきます。 行の長さがバッファのサイズを越える場合には、バッファは自動的に realloc(3) され、 引数 bufp および 引数 sizep で指定された変数もそれに従って更新されます。 ファイルを読み終わったら、このポインタを free(3) で解放する必要が あります。

引数 lenp の指す変数には、読み込んだレコードの長さを返します。 この長さには、レコード区切りの分も含みます。

この関数はレコード末の区切りを削除しません。 また、 引数 lenp の指す変数に返った値を利用すれば良いので冗長ですが、 レコード末に '\0' 文字を付加します。

EOF は、入力の長さが 0 バイトであることで判断します。

引数として gfs_pio_readdelim(f, bufp, sizep, lenp, "\n", 1) と指定すると、関数 gfs_pio_readline() と 等価になります。

RETURN VALUES

NULL
    正常終了を示します。

GFARM_ERR_NO_MEMORY
    メモリ不足のため処理を中止しました。 この場合も、bufp の指すポインタ変数の 指す領域を free(3) する必要がありますから注意してください。

その他 上記以外のエラーが生じたことを示します。

EXAMPLES

  GFS_PIO_READDELIM 関数の使用例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gfarm/gfarm.h>
int
main(int argc, char **argv)
{
	char *e;
	GFS_File gf;
	size_t bufsize = 0, delimlen = 1, len;
	char *buffer = NULL, *delim = "\n";
	e = gfarm_initialize(&argc, &argv);
	if (e != NULL) {
		fprintf(stderr, "gfarm_initialize: %s\n", e);
		return (EXIT_FAILURE);
	}
	while ((c = getopt(argc, argv, "d:D")) != -1) {
		switch (c) {
		case 'd':
			delim = optarg;
			delimlen = strlen(optarg);
			break;
		case 'D':
			delim = NULL;
			delimlen = 0;
			break;
		case '?':
		default:
			fprintf(stderr, "invalid option: %c\n", c);
			return (EXIT_FAILURE);
		}
	}
	if (optind >= argc) {
		fprintf(stderr, "missing gfarm filename\n");
		return (EXIT_FAILURE);
	}
	e = gfs_pio_open(argv[optind], GFARM_FILE_RDONLY, &gf);
	if (e != NULL) {
		fprintf(stderr, "%s: %s\n", argv[optind], e);
		return (EXIT_FAILURE);
	}
	e = gfs_pio_set_view_global(gf, 0);
	if (e != NULL) {
		fprintf(stderr, "%s: gfs_pio_set_view_global: %s\n",
		    argv[optind], e);
		return (EXIT_FAILURE);
	}
	while ((e = gfs_pio_readdelim(gf, &buffer, &bufsize, &len,
	    delim, delimlen)) == NULL && len > 0) {
		printf("<%6d/%6d >%s", len, bufsize, buffer);
	}
	if (buffer != NULL)
		free(buffer);
	if (e != NULL) {
		fprintf(stderr, "ERROR: %s\n", e);
		return (EXIT_FAILURE);
	}
	e = gfs_pio_close(gf);
	if (e != NULL) {
		fprintf(stderr, "gfs_pio_close: %s\n", e);
		return (EXIT_FAILURE);
	}
	e = gfarm_terminate();
	if (e != NULL) {
		fprintf(stderr, "gfarm_initialize: %s\n", e);
		return (EXIT_FAILURE);
	}
	return (EXIT_SUCCESS);
}

SEE ALSO

gfs_pio_open(3), gfs_pio_getline(3), gfs_pio_gets(3), gfs_pio_readline(3)