[comp.sys.ibm.pc.programmer] The Super strcat routine for lists ??

jeras@oracle.oracle.com (John Eras) (04/06/90)

In article <2619805E.18916@maccs.dcss.mcmaster.ca> cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) writes:
>In article <1577@dinl.mmc.UUCP> noren@dinl.UUCP (Charles Noren) writes:
>$Try using a variable argument list.  The approach
>$in Turbo C (as in MSC and other ANSI C compilers)
>$is to use the va_... functions (check for "va_..."
>$in the Turbo C Reference Guide).  The trick with
>$these functions is being able to tell when you reached
>$the end of the arguments.  In the sample code below
>$the end of the argument list to the function must have
>$NULL as the last argument.
>
>   There must be a way of doing this that doesn't require you to put
>a NULL as the last argument ... after all, functions like printf ()
>take variable-size argument lists and you don't have to say
>
>   printf ("%d%s\n", integervar, stringvar, NULL);

That's because printf() et al. doesn't give a damn what you put on the stack
as arguments, because it derives the arguments that it needs and their sizes
from the format string that you pass in.  So you could do:
    printf("%d%s\n");
and printf() wouldn't care--it would simply pull garbage off the stack.
Similarly, you could do:
    printf("%d%s\n", 20_gazillion_worthless_arguments);
and printf() would only pull the appropriate number of arguments off the
stack and ignore the rest.

As far as the original question (not included above) goes, the answers to
this problem are pretty trivial, and involve using one of the [s]printf()
family or using a null-terminated list of strings passed to a routine
with a strcat() loop.  Which one you use is a matter of personal preference.
--
AT:    jeras@oracle.com                              | "It's a terrible waste
BANG:  ...{pacbell,hplabs,apple,decwrl}!oracle!jeras | to lose one's .sig, or
FLAME: /dev/null                                     | not to have one at all."

vlrugvg@dutrun.UUCP (Ge van Geldorp) (04/08/90)

In article <2619805E.18916@maccs.dcss.mcmaster.ca> cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) writes:
]   There must be a way of doing this that doesn't require you to put
]a NULL as the last argument ... after all, functions like printf ()
]take variable-size argument lists and you don't have to say
]
]   printf ("%d%s\n", integervar, stringvar, NULL);
]

Yeah, but printf knows how many arguments to expect by scanning the
format string.


Ge van Geldorp
ge@dutlru2.tudelft.nl
...!uunet!hp4nl!dutlru2.tudelft.nl!ge

buck@granite.cr.bull.com (Ken Buck) (04/08/90)

In article <11817@ttidca.TTI.COM> svirsky@ttidca.TTI.COM (Bill Svirsky) writes:
  [stuff deleted]
>Or less obviously as:
>  strcat(strcat(strcat(strcpy(sys_string, "ls -l "), directory), "/"),filename);
>However, the printf functions have a relatively large overhead.  ...

This is true, of course, because the inclusion of sprintf() requires the
compiler provide the various conversion routines needed to interpret different
types of arguments, including >floating-point< types...

Note, however, that multiple calls to strcat() do incur an overhead as well,
in terms of: setting up function calling sequences, need to call strlen()
internally on each call to strcat(), and we needn't mention the ugliness...
[Translates into: bigger code than necessary, and perhaps *lots* slower...]
This can all be avoided, if you still don't want sprintf()+overhead, by
writing your variable-arg "catenate" routine such that it doesn't call strcat()
to do the catenation, but rather performs the catenation itself (via string-
traveling loops).
Personally, I prefer the simplicity of sprintf(), if memory is not a hassle.