Character strings are not a primitive netCDF external data type under the classic netCDF data model, 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 array access must be used to read and write character strings as variable data in netCDF datasets. Furthermore, variable-length strings are not supported by the netCDF classic interface except by convention; for example, you may treat a 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. However, the value of a character-string attribute in the classic netCDF interface 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 first dimension for the variable in Fortran 90). The length 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-length 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 either entire variable access or array access. The latter requires that you specify both a corner and a vector of edge lengths. The character-position dimension at the corner should be one for Fortran 90. 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: (n, 1, 1, ..., 1).
In Fortran 90, fixed-length strings may be written to a netCDF dataset without a terminating character, to save space. Variable-length strings should follow the C convention of writing strings with a terminating zero byte so that the intended length of the string can be determined when it is later read by either C or Fortran 90 programs. It is the users responsibility to provide such null termination.
If you are writing data in the default prefill mode (see next section), you can ensure that simple strings represented as 1-dimensional character arrays are null terminated in the netCDF file by writing fewer characters than the length declared when the variable was defined. That way, the extra unwritten characters will be filled with the default character fill value, which is a null byte. The Fortran intrinsic TRIM function can be used to trim trailing blanks from the character string argument to NF90_PUT_VAR to make the argument shorter than the declared length. If prefill is not on, the data writer must explicitly provide a null terminating byte.
Here is an example illustrating this way of writing strings to character array variables:
use netcdf implicit none integer status integer :: ncid, oceanStrLenID, oceanId integer, parameter :: MaxOceanNameLen = 20 character, (len = MaxOceanNameLen):: ocean ... status = nf90_create("foo.nc", nf90_NoClobber, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_def_dim(ncid, "oceanStrLen", MaxOceanNameLen, oceanStrLenId) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_def_var(ncid, "ocean", nf90_char, (/ oceanStrLenId /), oceanId) if(status /= nf90_NoErr) call handle_err(status) ... ! Leave define mode, which prefills netCDF variables with fill values status = nf90_enddef(ncid) if (status /= nf90_noerr) call handle_err(status) ... ! Note that this assignment adds blank fill ocean = "Pacific" ! Using trim removes trailing blanks, prefill provides null ! termination, so C programs can later get intended string. status = nf90_put_var(ncid, oceanId, trim(ocean)) if(status /= nf90_NoErr) call handle_err(status)