In netCDF-4, the NC_STRING type is introduced. It can store arrays of strings compactly.
By using the NC_STRING type, arrays of strings (char **) can be read and written to the file.
This allows attributes to hold more than one string. Since attributes are one-dimensional, using the classic model, an attribute could only hold one string, as an array of char. With the NC_STRING type, an array of strings can be stored in one attribute.
When reading data of type NC_STRING, the HDF5 layer will allocate memory to hold the data. It is up to the user to free this memory with the nc_free_string function. See nc_free_string.
int ncid, varid, i, dimids[NDIMS]; char *data[DIM_LEN] = {"Let but your honour know", "Whom I believe to be most strait in virtue", "That, in the working of your own affections", "Had time cohered with place or place with wishing", "Or that the resolute acting of your blood", "Could have attain'd the effect of your own purpose", "Whether you had not sometime in your life", "Err'd in this point which now you censure him", "And pull'd the law upon you."}; char *data_in[DIM_LEN]; printf("*** testing string attribute..."); { size_t att_len; int ndims, nvars, natts, unlimdimid; nc_type att_type; if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, NC_STRING, DIM_LEN, data)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_STRING || att_len != DIM_LEN) ERR; if (nc_close(ncid)) ERR; nc_exit(); /* Check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_STRING || att_len != DIM_LEN) ERR; if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR; for (i=0; i<att_len; i++) if (strcmp(data_in[i], data[i])) ERR; if (nc_free_string(att_len, (char **)data_in)) ERR; if (nc_close(ncid)) ERR; nc_exit(); }