Truncated strings with NXgetattr...

Freddie Akeroyd faa at isise.rl.ac.uk
Tue Apr 21 22:17:05 BST 1998


> 
> Hi,
> 
> I downloaded the newest version of Nexus from home page (napi.c,v 1.7
> 1998/04/08 06:43:42 nexus Exp) and am having a problem reading string
> attributes.
> 
> The problem I'm having is this, any string returned by NXgetattr is
> truncated by one character.  the code I'm using is essentially the
> following:
> 
> NXgetnextattr (exp_file_handle, attr_name, &length, &data_type)
> //check if attrib is "Nexus Version"
> if (!(strcmp (attr_name, "Nexus Version")))
> {
>    nexus_version = (char *) malloc(length*sizeof(char));
>    NXgetattr (exp_file_handle, attr_name, nexus_version, &length,
> &data_type)
> }
> 
> If I examine length before NXgetattr, it is 3.  After calling NXgetattr,
> it is only 2.  And the returned string is truncated by one character
> from expected.
> 
> Thanks!
> 
> Brian Tieman
> SRICAT--APS
> 
I think the problem is related to whether the length of a string is
the number of characters in it, or the space needed to store those
characters, and NeXus' interpretation of these.

In C you traditionally allocate n+1 bytes for a string of n characters and
make the final character '\0' to mark the end of the string - if you
don't do this, functions like "strcmp()" and "strcpy()" will not
work properly.

NeXus makes sure that any string it returns to you is "NULL
terminated". While "NXgetnextattr()" returns the number of characters in
a string, "NXgetattr()" assumes (for a string attribute) that the "length"
parameter you pass to it is the number of bytes that you have actually
allocated, and so the maximum size of string it will return is
"length-1".  If you change your code to:

NXgetnextattr (exp_file_handle, attr_name, &length, &data_type);
//check if attrib is "Nexus Version"
if (!(strcmp (attr_name, "Nexus Version")))
{
   length++;	// allow space for a '\0' to be appended 
   nexus_version = (char *) malloc(length * sizeof(char));
   NXgetattr (exp_file_handle, attr_name, nexus_version, &length,
              &data_type);
}

It should work, but the question is: should NeXus NULL terminate
strings only if you pass it more space than is required (like strncpy()
does), or should it always NULL terminate even if that means chopping
off a character at the end (like strncat() does)? What do people think
is more natural? The advantage with the current method is that if you
get things wrong you just loose a character rather than get a
"segmentation violation".

Regards,

Freddie

-- 
Freddie Akeroyd                        Email:  Freddie.Akeroyd at rl.ac.uk
ISIS Facility                          Tel:    +44 1235 445457
Rutherford Appleton Laboratory         Fax:    +44 1235 445720
Chilton, DIDCOT, OX11 OQX, GB          WWW:    http://www.isis.rl.ac.uk/



More information about the NeXus mailing list