variable number of strings passed to function - how?
Doug Gwyn
gwyn at smoke.BRL.MIL
Sun Oct 23 05:03:17 AEST 1988
In article <434 at tutor.UUCP> pete at tutor.UUCP (Peter Schmitt) writes:
>I want to write a function that accepts a variable number of string
>arguments. What is a possible way to do this?
There are two portable ways to do this as stated, using variable-
argument facilities (you could also pass as a fixed argument a
variable-sized data structure containing the strings). Either a
count of the number of strings is passed as the first argument,
or a null pointer (end marker) is passed after the last string.
The two standard variable-argument facilities are associated with
the headers <varargs.h> (most current implementations) and
<stdarg.h> (ANSI C conforming implementations). I generally code
for both, using #if __STDC__ as necessary to control compilation
of the correct variation of the code. You should refer to your
reference manual for details of these facilities, but here is an
example extracted from the BRL/VLD MUVES project source code:
#include <stdio.h>
#include <string.h>
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <Er.h> /* error-logging package interface */
#include <Mm.h> /* memory-management package iface */
/*
IoOpenFile() opens the file named by the concatenation of its
variable character-string arguments for reading; it returns NULL
if memory could not be allocated to build the pathname or if the
file could not be opened (in which case ErIndex is set to
`errnum'). The final argument must be (char *)NULL.
*/
#if __STDC__
FILE *
IoOpenFile( long errnum, ... )
{
#else
/*VARARGS*/
FILE *
IoOpenFile( va_alist )
va_dcl
{
long errnum;
#endif
va_list ap;
register FILE *fp; /* opened file stream pointer */
register char *p; /* -> filename segment */
register char *cp; /* -> end of partial filename */
register int name_len; /* string allocation length */
char *fname; /* full path name of file */
/* allocate space for filename */
#if __STDC__
va_start( ap, errnum );
#else
va_start( ap );
errnum = va_arg( ap, long );
#endif
for ( name_len = 1; (p = va_arg( ap, char * )) != NULL; )
name_len += strlen( p );
va_end( ap );
if ( (fname = cp = MmVAllo( name_len, char )) == NULL )
return (FILE *)NULL; /* ErIndex already set */
/* construct concatenated filename */
#if __STDC__
va_start( ap, errnum );
#else
va_start( ap );
(void)va_arg( ap, long ); /* skip errnum */
#endif
while ( (p = va_arg( ap, char * )) != NULL )
while ( (*cp = *p++) != '\0' )
++cp;
va_end( ap );
/* try to open the file */
if ( (fp = fopen( fname, "r" )) == NULL )
ErSet( errnum );
/* deallocate filename space */
MmVFree( name_len, char, fname );
return fp; /* (may be NULL) */
}
More information about the Comp.lang.c
mailing list