strncat is insufficient

Karl Heuer karl at haddock.ima.isc.com
Thu Aug 16 07:26:56 AEST 1990


In article <12570054 at hpclscu.HP.COM> shankar at hpclscu.HP.COM (Shankar Unni) writes:
>I think this is an appropriate place for suggestions for extensions to the
>language, too, in addition to questions about clarifications of items in
>the current standard...

I somewhat agree, as long as we're careful not to let the discussion explode
into the usual "let's make C into Ada" nonsense.

>>[Rahul notes that strncat() doesn't do what he usually wants]
>[Shankar shows how to do it in terms of strlen() and strncat()]

In my opinion, the string library was poorly designed in the first place; and
adding a strlimcat() along the lines you suggest would be compounding the
error.

Naive use of strcat() gives you quadratic behavior, which can be avoided by
operating at the *end* of the string instead of the beginning.  With this in
mind, I would propose replacement functions along these lines:

	#include <nstring.h>
	char *nstrend(char const *s) {
	    while (*s != '\0') ++s;
	    return (char *)s;
	}
	char *nstrcpy(char *d, char const *s) {
	    while (*s != '\0') *d++ = *s++;
	    return d;
	}
	char *nstrlimcpy(char *d, char const *dlim, char const *s) {
	    while (d < dlim-1 && *s != '\0') *d++ = *s++;
	    *d = '\0';
	    return (d);
	}

Notes:
- The `n' prefix means `new', and is used to distinguish these from the
  existing string library.  Better names are possible.

- Pointer-valued nstring functions normally point to the end of the
  destination, i.e. to the terminating null character.

- As with <string.h>, these would probably be optimized to death by a serious
  vendor.  They are likely to perform slightly better, since the algorithm
  will probably already have the correct return value in hand when the
  algorithm terminates.  (The old-string functions often have to save a copy
  of an incoming value for no other reason than to return it when done.)

- There is no `nstrcat'.  You probably don't need it: the old-string idiom
  `path=strcat(strcat(strcpy(buf, dir), "/"), file)' becomes
  `nstrcpy(nstrcpy(nstrcpy(path=buf, dir), "/"), file)'.  If you really need
  it, you can use `#define nstrcat(d, s) nstrcpy(nstrend(d), s)'.

- The extra arg to nstrlimcpy() is a limit pointer, not a length.  This way it
  will remain constant even if you're pasting several strings together.

- Unlike strncpy(), nstrlimcpy() always terminates with exactly one '\0'.
  This is the more useful behavior, now that the 14-character directory buffer
  is obsolete.

- Even if this package is generally agreed to be better than <string.h>, there
  is very little incentive for standardizing it, given that the old-string
  library already exists and is standardized.

Karl W. Z. Heuer (karl at kelp.ima.isc.com or ima!kelp!karl), The Walking Lint



More information about the Comp.std.c mailing list