Categories:
.NET (357)
C (330)
C++ (183)
CSS (84)
DBA (2)
General (7)
HTML (4)
Java (574)
JavaScript (106)
JSP (66)
Oracle (114)
Perl (46)
Perl (1)
PHP (1)
PL/SQL (1)
RSS (51)
Software QA (13)
SQL Server (1)
Windows (1)
XHTML (173)
Other Resources:
How can I write a function that takes a variable number of arguments?
How can I write a function that takes a variable number of arguments?
✍: Guest
Use the facilities of the <stdarg.h> header.
Here is a function which concatenates an arbitrary number of strings into malloc'ed memory:
#include <stdlib.h> /* for malloc, NULL, size_t */
#include <stdarg.h> /* for va_ stuff */
#include <string.h> /* for strcat et al. */
char *vstrcat(const char *first, ...)
{
size_t len;
char *retbuf;
va_list argp;
char *p;
if(first == NULL)
return NULL;
len = strlen(first);
va_start(argp, first);
while((p = va_arg(argp, char *)) != NULL)
len += strlen(p);
va_end(argp);
retbuf = malloc(len + 1); /* +1 for trailing \0 */
if(retbuf == NULL)
return NULL; /* error */
(void)strcpy(retbuf, first);
va_start(argp, first); /* restart; 2nd scan */
while((p = va_arg(argp, char *)) != NULL)
(void)strcat(retbuf, p);
va_end(argp);
return retbuf;
}
(Note that a second call to va_start is needed to re-start the scan when the argument list is processed a second time. Note the calls to va_end: they're important for portability, even if they don't seem to do anything.)
A call to vstrcat looks something like
char *str = vstrcat("Hello, ", "world!", (char *)NULL);
Note the cast on the last argument (Also note that the caller must free the returned, malloc'ed storage.)
vstrcat accepts a variable number of arguments, all of type char *. Here is an example which accepts a variable number of arguments of different types; it is a stripped-down version of the familiar printf function. Note that each invocation of va_arg() specifies the type of the argument being retrieved from the argument list.
(The miniprintf function here uses baseconv. It is significantly imperfect in that it will not usually be able to print the smallest integer, INT_MIN, properly.)
#include <stdio.h>
#include <stdarg.h>
#ifdef MAIN
void miniprintf(const char *, ...);
main()
{
miniprintf("Hello, world!\n");
miniprintf("%c %d %s\n", '1', 2, "three");
miniprintf("%o %d %x\n", 10, 10, 10);
miniprintf("%u\n", 0xffff);
return 0;
}
#endif
extern char *baseconv(unsigned int, int);
void
miniprintf(const char *fmt, ...)
{
const char *p;
int i;
unsigned u;
char *s;
va_list argp;
va_start(argp, fmt);
for(p = fmt; *p != '\0'; p++) {
if(*p != '%') {
putchar(*p);
continue;
}
switch(*++p) {
case 'c':
i = va_arg(argp, int);
/* *not* va_arg(argp, char); see Q 15.10 */
putchar(i);
break;
case 'd':
i = va_arg(argp, int);
if(i < 0) {
/* XXX won't handle INT_MIN */
i = -i;
putchar('-');
}
fputs(baseconv(i, 10), stdout);
break;
case 'o':
u = va_arg(argp, unsigned int);
fputs(baseconv(u, 8), stdout);
break;
case 's':
s = va_arg(argp, char *);
fputs(s, stdout);
break;
case 'u':
u = va_arg(argp, unsigned int);
fputs(baseconv(u, 10), stdout);
break;
case 'x':
u = va_arg(argp, unsigned int);
fputs(baseconv(u, 16), stdout);
break;
case '%':
putchar('%');
break;
}
}
va_end(argp);
}
2015-06-15, 1041👍, 0💬
Popular Posts:
How to make elements invisible? Change the "visibility" attribute of the style object associated wit...
How To Create an Add-to-Netvibes Button on Your Website? - RSS FAQs - Adding Your Feeds to RSS News ...
What does static variable mean? There are 3 main uses for static variables: If you declare within a ...
.NET INTERVIEW QUESTIONS - Where do you specify session state mode in ASP.NET ? The following code e...
How To Enter a New Row into a Table Interactively? - Oracle DBA FAQ - Introduction to Oracle SQL Dev...