strcat and strncat problem on different machines

Gerald I. Evenden gie at charon.er.usgs.gov
Sat Jul 16 13:00:25 EDT 1994


>From: BAKERWL at UWYO.EDU
>Date: Sat, 16 Jul 1994 09:54:30 -0600 (MDT)
>Subject: strcat and strncat problem on different machines
>Sender: grass-lists-owner at max.cecer.army.mil
>
>I have a small function in the r.le programs that works fine under
>SunOS 4.1.3 on my Sparcstation, but fails under Solaris 2.* and on
>other machines.  The function uses getchar and strcat to get user
>digital input from the screen and dump it into an array.  Here is 
>a typical statement to read digits and append them to the end of 
>a character array called "num":
>
>	while ((c=getchar()) && isdigit(c)) strcat(num, &c);

I am sorry, but this is terrible code for several reasons.

How about the following alternative:

#include <stdio.h>
#include <string.h>
#define MAX <some pos. integer>
	...
	char num[MAX+1], *s;
	int c, i;
	...
	for (i = 0, s = num ; i < MAX && (c = getchar()) && isdigit(c); ++i)
		*s++ = c;
	*s = '\0';
	if (i >= MAX) {
		<error condition for overflowing "num">
	}

At this point, "num" is a properly composed string.  This is SAFE and
general and it may be faster because *strcat* does not have to continually
search for the end of string.  If there are other elements previously
added to num, then i and s may have been pre initialized by previous
operations and should not be in the init part of the *for*.  An
alternative, in this case could also be:

	i = strlen(num);
	for (i = strlen(num), s = num+i ; i < MAX   ...

This, of course, assumes a properly constucted string in num.

>Earlier, Changyong Cao told me that this fails under Linux, since
>strcat(num, &c) appends a bunch of strange characters instead of
>just one.  He found that the following substitution works:
>
>	while ((c=getchar()) && isdigit(c)) strncat(num, &c, 1);

Just as bad!

>While I will probably do this substitution and hope for the best,
>I wonder if anyone knows why this happens or whether there is a 
>more general solution.  Also, for some reason on some machines
>my function only reads a couple of digital characters, then stops.
>Anyone know why?
>
>	Bill Baker
>	bakerwl at uwyo.edu

In both initial examples, the other bummer is making a pointer
to an assumed typed int and giving it as an argument to a function
that assumes it to be a pointer to a character.  These are NOT
the same animals and how this casting is going to be performed
may vary between machines.

If c is declared as char, then we will have multiple conversions
to and from type int for the getchar and isdigit functions.  Also,
there may be a problem of detecting c == EOF where EOF is -1.

But PLEASE make sure you do not overflow the string.

Gerald (Jerry) I. Evenden   Internet: gie at charon.er.usgs.gov
voice: (508)563-6766          Postal: P.O. Box 1027
  fax: (508)457-2310                  N.Falmouth, MA 02556-1027



More information about the grass-dev mailing list