7.15 文字列値を読み書きする
文字列は基本的なNetCDF外部データ型ではありません。なぜならば、FORTRANでは可変長の文字列の抽象化をサポートしていないからです。(FORTRANのLEN関数は文字列の動的な長さではなく、静的な長さを返します。)その結果、NetCDFインターフェースでは文字列は単一のオブジェクトとして読み書きすることができません。文字列は文字の配列として扱わなければならないのです。したがって、NetCDFファイルの変数データとして文字列を読み書きするためには配列アクセスをしなければなりません。さらに、NetCDFインターフェースでは可変長の文字列は規約による場合を除いてはサポートされていません。例えば、null文字を文字列の終端として扱うことは可能ですが、NetCDF変数に読み書きされる文字列の長さを明示しなければなりません。
文字列を属性値として扱えば使用しやすくなります。それは文字列がアクセスする際に一つの単位として扱われるからです。しかしながら、文字列の属性値の値はやはり固有の長さを持つ文字の配列であり、その長さは属性が定義されるときに指定される必要があります。
文字列値を持つ変数を定義する際には、文字列位置次元(character-position dimension)を最も早く変化する次元として使用しなければなりません(Cの変数において最後の次元)。文字列次元の長さは文字列変数に格納されるあらゆる文字列の最大長です。最大長の列を格納するスペースは、使用するか否かにかかわらず、文字列変数のディスク表現の中に割り当てられます。仮に、2個以上の変数の最大長が同じである場合には、変数の形を定義するにあたって同じ文字位置次元を使用しても構いません。
文字列変数に文字列の値を書き込むには、全変数アクセスもしくは配列アクセスを使用します。後者を使用する場合には隅と縁の長さのベクトルの両方を指定する必要があります。文字位置次元の隅はCにおいて0です。もし書き込む列の長さがnと仮定すると、縁の長さのベクトルは文字位置次元にnを指定し、他の次元にはすべて1を指定します:(1, 1, … , 1, n)。
Cにおいては、固定長の列はnull文字無しにNetCDFファイルに書き込むことができます。可変長の列はnull文字が必要となります。それによって、後で読み取られる際に目的の列の長さが明確になるからです。
この例では、記録変数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);
Quadralay Corporation http://www.webworks.com Voice: (512) 719-3399 Fax: (512) 719-3606 sales@webworks.com |