Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!nrl-cmf!cmcl2!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn ) Newsgroups: comp.lang.c Subject: Re: variable number of strings passed to function - how? Message-ID: <8718@smoke.BRL.MIL> Date: 22 Oct 88 19:03:17 GMT References: <434@tutor.UUCP> Reply-To: gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 100 In article <434@tutor.UUCP> pete@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 (most current implementations) and (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 #include #if __STDC__ #include #else #include #endif #include /* error-logging package interface */ #include /* 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) */ }