Go to the previous, next section.
Character strings are not a primitive netCDF data type, in part because
FORTRAN does not support the abstraction of variable-length character
strings (the FORTRAN LEN
function returns the static length of a
character string, not its dynamic length). As a result, a character
string cannot be written or read as a single object in the netCDF
interface. Instead, a character string must be treated as an array of
characters, and hyperslab access must be used to read and write
character strings as variable data in netCDF files. Furthermore,
variable-length strings are not supported by the netCDF interface except
by convention; for example, you may treat a null (zero) byte as
terminating a character string, but you must explicitly specify the
length of strings to be read from and written to netCDF variables.
Character strings as attribute values are easier to use, since the strings are treated as a single unit for access; no hyperslab access is necessary (or possible) for attributes. However, the value of a character-string attribute is still an array of characters with an explicit length that must be specified when the attribute is defined.
When you define a variable that will have character-string values, use a character-position dimension as the most quickly varying dimension for the variable (the last dimension for the variable in C, the first in FORTRAN). The size of the character-position dimension will be the maximum string length of any value to be stored in the character-string variable. Space for maximum-size strings will be allocated in the disk representation of character-string variables whether you use the space or not. If two or more variables have the same maximum length, the same character-position dimension may be used in defining the variable shapes.
To write a character-string value into a character-string variable, use
hyperslab access. This requires that you specify both a corner and a
vector of edge lengths. The character-position dimension at the corner
should be zero (one for FORTRAN). If the length of the string to be
written is n
, then the vector of edge lengths will specify
n
in the character-position dimension, and one for all the other
dimensions, i.e., (1, 1, ..., 1, n)
or (n, 1, 1, ...,
1)
in FORTRAN.
In C, fixed-size strings may be written to a netCDF file without the terminating null byte, to save space. Variable-length strings should be written with a terminating null byte so that the intended length of the string can be determined when it is later read.
Here is an example that defines a record variable, tx
, for
character strings and stores a character-string value into the third
record using ncvarput
. In this example, we assume the string
variable and data are to be added to an existing netCDF file named
`foo.nc' that already has an unlimited record dimension time
.
#include "netcdf.h" ... int ncid; /* netCDF ID */ int chid; /* dimension ID for char positions */ int timeid; /* dimension ID for record dimension */ int tx_id; /* variable ID */ #define TDIMS 2 /* dimensionality of tx variable */ int tx_dims[TDIMS]; /* variable shape */ long tx_start[TDIMS]; long tx_count[TDIMS]; static char tx_val[] = "example string"; /* string to be put */ ... ncid = ncopen("foo.nc", NC_WRITE); ncredef(ncid); /* enter define mode */ ... /* define character-position dimension for strings of max length 40 */ chid = ncdimdef(ncid, "chid", 40L); ... /* define a character-string variable */ tx_dims[0] = timeid; tx_dims[1] = chid; /* character-position dimension last */ tx_id = ncvardef (ncid, "tx", NC_CHAR, TDIMS, tx_dims); ... ncendef(ncid); /* leave define mode */ ... /* write tx_val into tx netCDF variable in record 3 */ tx_start[0] = 3; /* record number to write */ tx_start[1] = 0; /* start at beginning of variable */ tx_count[0] = 1; /* only write one record */ tx_count[1] = strlen(tx_val) + 1; /* number of chars to write */ ncvarput(ncid, tx_id, tx_start, tx_count, (void *) tx_val);
In FORTRAN, fixed-size strings may be written to a netCDF file without a terminating character, to save space. Variable-length strings should follow the C convention of writing strings with a terminating null byte so that the intended length of the string can be determined when it is later read by either C or FORTRAN programs.
The FORTRAN interface for reading and writing strings requires the use
of different subroutines for accessing string values and numeric values,
because standard FORTRAN does not permit the same formal parameter to be
used for both character values and numeric values. An additional
argument, specifying the declared length of the character string passed
as a value, is required for NCVPTC
and NCVGTC
. The actual
length of the string is specified as the value of the hyperslab
edge-length vector corresponding to the character-position dimension.
Here is an example that defines a record variable, tx
, for
character strings and stores a character-string value into the third
record using NCVPTC
. In this example, we assume the string
variable and data are to be added to an existing netCDF file named
`foo.nc' that already has an unlimited record dimension
time
.
INCLUDE 'netcdf.inc' ... PARAMETER (TDIMS=2) ! number of TX dimensions PARAMETER (TXLEN = 15) ! length of example string INTEGER NCID, RCODE INTEGER CHID ! char position dimension id INTEGER TIMEID ! record dimension id INTEGER TXID ! variable ID INTEGER TXDIMS(TDIMS) ! variable shape INTEGER TSTART(TDIMS), TCOUNT(TDIMS) ! hyperslab CHARACTER*40 TXVAL ! max length 40 DATA TXVAL /'example string'/ ... TXVAL(TXLEN:TXLEN) = CHAR(0) ! null terminate ... NCID = NCOPN('foo.nc', NCWRITE, RCODE) CALL NCREDF(NCID, RCODE) ! enter define mode ... * define character-position dimension for strings of max length 40 CHID = NCDDEF(NCID, "chid", 40, RCODE) ... * define a character-string variable TXDIMS[1] = CHID ! character-position dimension first TXDIMS[2] = TIMEID TXID = NCVDEF(NCID, "tx", NCCHAR, TDIMS, TXDIMS, RCODE) ... CALL NCENDF(NCID, RCODE) ! leave define mode ... * write txval into tx netCDF variable in record 3 TSTART[1] = 0 ! start at beginning of variable TSTART[2] = 3 ! record number to write TCOUNT[1] = TXLEN ! number of chars to write TCOUNT[2] = 1 ! only write one record CALL NCVPTC (NCID, TXID, TSTART, TCOUNT, TXVAL, 40, RCODE)
Go to the previous, next section.