Up|<<Prev|Next>>


7.15 文字列値を読み書きする

文字 基本的なNetCDF外部データ型ではありません。なぜならば、FORTRANでは可変長の文字列の抽象化をサポートしていないからです。( FORTRANの LEN 関数は文字列の動的な長さではなく、静的な長さを返します。) その結果、NetCDFインターフェースでは文字列は単一のオブジェクトとして読み書きすることが出来ません。文字列は文字の配列として扱わなければならないのです。それ故、NetCDFファイルの変数データとして文字列を読み書きするためには配列アクセスをしなければなりません。さらに、NetCDFインターフェースでは可変長の文字列は慣習による場合を除いてはサポートされていません。例えば、零バイトを文字列を終了するものとして扱うことは可能ですが、NetCDF変数に読み書きされる文字列の長さを明示しなければなりません。

文字列を属性値として扱えば使用しやすくなる。それは文字列がアクセスする際に一つの単位として扱われるからである。しかしながら、文字列の属性値の値はやはり固有の長さを持つ文字の配列であり、その長さは属性が定義されるときに指定される必要がある。

文字列値を持つ変数をを定義する際には, 文字列位置次元 character-position dimension を最も早く変化する次元として使用しなければならない。 ( C の変数において最後の 次元 f)文字列次元の長さは文字列変数に格納されるあらゆる文字列の最大長である。 最大長の列を格納するスペースは、使用するか否かにかかわらず、文字列変数のディスク表現の中に割り当てられる。 仮に、2個以上の変数の最大長が同じである場合には、変数の形を定義するにあたって同じ文字位置次元を使用しても良い。

文字列変数に文字列の値を書き込むには、全変数アクセスもしくは配列アクセスを使用します。後者を使用する場合には隅と縁の長さのベクトルの両方を指定する必要があります。文字位置次元の隅はC. においてzero です。 もし書き込む列の長さが n と仮定すると、縁の長さのベクトルは文字位置次元に n を指定し、他の次元には全て1を指定します: (1, 1, ... , 1, n)

Cにおいては、固定長の列は終了文字の零バイト無しにNetCDFファイルに書き込むことが出来ます。 可変長の列は終了文字のゼロバイトが必要となります。それによって、後で読み取られる際に目的の列の長さが明確になるからです。

この例では、記録変数 tx を文字列用に定義して、3番目の記録に nc_put_vara_text を使用して文字列値を格納します。ここで、この文字列変数とその値は time という無制限記録次元を持つ既存のNetCDFファイル foo.nc に書き加えると仮定します。

#include <netcdf.h>
   ... 
int  ncid;            /* NetCDF ID */
int  chid;            /* 文字の位置の次元ID */
int  timeid;          /* 記録次元の次元ID */
int  tx_id;           /* 変数ID */
#define TDIMS 2       /* tx変数のランク */
int tx_dims[TDIMS];   /* 変数の形 */
size_t tx_start[TDIMS];
size_t tx_count[TDIMS];
static char tx_val[] =
        "example string"; /* 置かれる文字列 */
   ... 
status = nc_open("foo.nc", NC_WRITE, &ncid);
if (status != NC_NOERR) handle_error(status);
status = nc_redef(ncid);       /* 定義モードに入る */
if (status != NC_NOERR) handle_error(status);
   ... 
/* 最大長が40文字の文字列における文字の位置の次元を定義する */
status = nc_def_dim(ncid, "chid", 40L, &chid);
if (status != NC_NOERR) handle_error(status);
   ... 
/* 文字列変数を定義する */
tx_dims[0] = timeid;
tx_dims[1] = chid;    /* 最後の文字の位置の次元 */
status = nc_def_var (ncid, "tx", NC_CHAR, TDIMS, tx_dims, &tx_id);
if (status != NC_NOERR) handle_error(status);
   ... 
status = nc_enddef(ncid);       /* 定義モードを抜ける */
if (status != NC_NOERR) handle_error(status);
   ... 
/* 記録3においてtx_val を tx NetCDF 変数に書き込む*/
tx_start[0] = 3;      /* 書き込む記録の数 */
tx_start[1] = 0;      /* 変数の先頭から開始 */
tx_count[0] = 1;      /* 一つの記録のみ書き込む */
tx_count[1] = strlen(tx_val) + 1;  /* 書き込む文字数 */
status = nc_put_vara_text(ncid, tx_id, tx_start, tx_count, tx_val);
if (status != NC_NOERR) handle_error(status);

Up|<<Prev|Next>>