strcat and strncat problem on different machines

From: BAKERWL@UWYO.EDU
Date: Sat, 16 Jul 1994 09:54:30 -0600 (MDT)
Subject: strcat and strncat problem on different machines
Sender: grass-lists-owner@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@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@charon.er.usgs.gov
voice: (508)563-6766 Postal: P.O. Box 1027
  fax: (508)457-2310 N.Falmouth, MA 02556-1027