Function with unknown number of parameters in C - c

How can I write (if it's possible at all...) a function which takes an unknown number of parameters in C99 (the return type is constant)?

Yes you can do it in C using what are referred to as Variadic Functions.
The standard printf() and scanf() functions do this, for example.
Put the ellipsis (three dots) as the last parameter where you want the 'variable number of parameters to be.
To access the parameters include the <stdarg.h> header:
#include <stdarg.h>
And then you have a special type va_list which gives you the list of arguments passed, and you can use the va_start, va_arg and va_end macros to iterate through the list of arguments.
For example:
#include <stdarg.h>
int myfunc(int count, ...)
{
va_list list;
int j = 0;
va_start(list, count);
for(j=0; j<count; j++)
{
printf("%d", va_arg(list, int));
}
va_end(list);
return count;
}
Example call:
myfunc(4, -9, 12, 43, 217);
A full example can be found at Wikipedia.
The count parameter in the example tells the called function how many arguments are passed. The printf() and scanf() find that out via the format string, but a simple count argument can do it too. Sometimes, code uses a sentinel value, such as a negative integer or a null pointer (see
execl()
for example).

Related

How can I add all the elements with a function with variable parameters in C? [duplicate]

How can I write (if it's possible at all...) a function which takes an unknown number of parameters in C99 (the return type is constant)?
Yes you can do it in C using what are referred to as Variadic Functions.
The standard printf() and scanf() functions do this, for example.
Put the ellipsis (three dots) as the last parameter where you want the 'variable number of parameters to be.
To access the parameters include the <stdarg.h> header:
#include <stdarg.h>
And then you have a special type va_list which gives you the list of arguments passed, and you can use the va_start, va_arg and va_end macros to iterate through the list of arguments.
For example:
#include <stdarg.h>
int myfunc(int count, ...)
{
va_list list;
int j = 0;
va_start(list, count);
for(j=0; j<count; j++)
{
printf("%d", va_arg(list, int));
}
va_end(list);
return count;
}
Example call:
myfunc(4, -9, 12, 43, 217);
A full example can be found at Wikipedia.
The count parameter in the example tells the called function how many arguments are passed. The printf() and scanf() find that out via the format string, but a simple count argument can do it too. Sometimes, code uses a sentinel value, such as a negative integer or a null pointer (see
execl()
for example).

In C, how to pass a variable number of arguments (say, 50+) to a function which va_start() understands prior to calling vsnprintf()?

Question
Is there a way to pass many arguments to MyPrint() below using some kind of array containing a list of pointers to strings that va_start() understands before calling vsnprintf()?
Example of a format string specifier. It would be nice to create an array of the corresponding values and pass that to MyPrint() rather than individually passing each argument. I don't know if it's possible for va_start() to understand it. :(
"[0x%llX][%u] %s --- A=%llu (0x%llX) B=%llu (0x%llX) C=%llu (0x%llX) X=%llu (0x%llX) Y=%llu (0x%llX) Z=%llu (0x%llX)"
Details
MyPrint() calls vsnprintf() which prints a formatted list of arguments to a character array. The declaration for vsnprintf() is shown below:
int vsnprintf(char *arr, size_t len, const wchar_t *format, va_list args);
Parameters
arr: Pointer to the character array where output is to be printed
len: Maximum number of characters that can be written to the array
format: Format in which the output will be printed
args: Pointer to the list of arguments to be printed
Demo
#include <stdio.h>
#include <stdarg.h>
int MyPrint(char* buffer, int bufferSize, const char *format, ...)
{
int len = 0;
va_list arguments;
va_start(arguments, format);
len = vsnprintf(buffer, bufferSize, format, arguments);
va_end(arguments);
return len;
}
int main()
{
char buffer[256];
MyPrint(buffer, 256, "%s %s","Hello","World");
printf("%s",buffer);
return 0;
}
Is there a way to pass many arguments to MyPrint() below using some kind of array containing a list of pointers to strings that va_start() understands before calling vsnprintf()?
The only defined ways to initialize a va_list, such as vsnprintf() requires as a parameter, are
via the va_start() macro, operating in the context of a variadic function to form a va_list from the function's variadic arguments, and
via the va_copy() macro, to make a copy of another va_list.
There is no mechanism in standard C to form a va_list from the elements of an array, except by passing them all, individually, to a variadic function.
Variadic functions are about coding flexibility, not data flexibility. If you want a function that handles arrays of data, then write a (non-variadic) one that does so.
Whenever you consider writing your own varargs function, smack yourself in the head and repeat the mantra: "varargs is not the answer". Only if you still have varargs in your head after a few iterations of that should you should consider actually investigating that option.

C - Scanf with only read/write [duplicate]

How can I write (if it's possible at all...) a function which takes an unknown number of parameters in C99 (the return type is constant)?
Yes you can do it in C using what are referred to as Variadic Functions.
The standard printf() and scanf() functions do this, for example.
Put the ellipsis (three dots) as the last parameter where you want the 'variable number of parameters to be.
To access the parameters include the <stdarg.h> header:
#include <stdarg.h>
And then you have a special type va_list which gives you the list of arguments passed, and you can use the va_start, va_arg and va_end macros to iterate through the list of arguments.
For example:
#include <stdarg.h>
int myfunc(int count, ...)
{
va_list list;
int j = 0;
va_start(list, count);
for(j=0; j<count; j++)
{
printf("%d", va_arg(list, int));
}
va_end(list);
return count;
}
Example call:
myfunc(4, -9, 12, 43, 217);
A full example can be found at Wikipedia.
The count parameter in the example tells the called function how many arguments are passed. The printf() and scanf() find that out via the format string, but a simple count argument can do it too. Sometimes, code uses a sentinel value, such as a negative integer or a null pointer (see
execl()
for example).

va_arg always runs 4 times

I am learning stdarg.h in c i am trying to print all arguments passed to function without knowing how many arguments are there but yet i have not come up with solution, during this this happened, no matter what i pass to strtest.
It always print 0. 1. 2. 3.
void strtest(char *fmt, ...){
va_list argp;
int i = 0;
va_start(argp, fmt);
while(va_arg(argp, char*))
printf("%d\t", i++ );
va_end(argp);
}
int main(int argc, char *argv[]){
strtest("s");
printf("\n");
return 0;
}
There's no standard mechanism that will tell you the number of arguments passed to a varargs function. Functions like printf() work because they can determine the number of arguments by examining the format string.
Here is an example showing one way to pass an unknown number of arguments.
#include <stdio.h>
#include <stdarg.h>
void print (char *first, ...)
{
va_list argptr;
char *next;
va_start (argptr, first);
next = first;
while (next) {
printf ("%s\n", next);
next = va_arg(argptr, char*);
}
va_end (argptr);
}
int main(void)
{
print("hello","world", NULL); // NULL as sentinel
return 0;
}
Program output
hello
world
Perhaps you can adapt this to your needs using int arguments.
This is the definition of stdarg.h in the ISO 9899 WG14 n1256
The header <stdarg.h> declares a type and defines four macros, for advancing
through a list of arguments whose number and types are not known to the called function
when it is translated
You have to pass the number of arguments, and possibly the types as well, to the caller. This doesn't have to be done by directly passing the number of arguments, there are other methods such as the one used in printf.
You could pass a sentinel to the function like this
strtest("s", (char*)0);
such that the function can notice that it is at the end of the argument list.
If you look at the man page for stdarg, va_arg includes this text
If there is no next argument, or if type is not compatible with the
type of the actual next argument (as promoted according to the
default argument promotions), random errors will occur.
Unless you call strtest with a NULL as the last argument, va_arg will just keep reading until it hits something that makes it stop. Think of what you are doing right now as equivalent to reading an array outside its bounds.
I'm surprised it was running 4 times no matter what though. I would have expected the count to be equal to the number of args you passed to strtest plus 2 or more.

How can I build a function that can receive 3 or 4 arguments ?

I know it's a basic question ,
How can I build\write a function that can receive 3 or 4 arguments ?
Or more general , How can i write a function that can receive unknown number of arguments ?
Thanks !
To define a function with an unknown number of arguments the first one must be known. Then you have to include the stdarg.h library to access the arguments using it's functions: va_start, va_args, va_en and the type va_list.
In general the function is defined this way. Note that the first argument is not always of type int. It can be const char * for more controle on your arguments. for exemple in the printf() function.
type myFunction(int n, ...)
{
int i;
va_list args;
va_start(args, n);
for (i=0; i<n; i++){
// your argument is va_arg(args, int);
//... do something with your aruments
}
va_end(args);
// return your value
}
check these resources for more about stdarg.h http://www.cplusplus.com/reference/cstdarg/
or http://en.wikipedia.org/wiki/Stdarg.h
You need a function with a variadic parameter list. Use ellipses to define it:
void foo(int first, ...)
{
}
Use var_args to parse the parameters. The first parameter is usually used to
address the other parameters
control how the other parameters shall be treated
For the more general aspect, you can store the arguments in an array. And you can then pass a pointer of the array or the array itself to the actual function. This permits you to manipulate those arguments.

Resources