Noob question: How do you check if you're out of arguments in a variable argument list? I'd like to use it in a loop.
Noob question: How do you check if you're out of arguments in a variable argument list? I'd like to use it in a loop.
You can't just search a valist to work out the end.
Either
- encode the number of parameters, say a format string, like printf -> printf(3): formatted output conversion - Linux man page
- mark the end of the list with a special value, like execl -> execl(3): execute file - Linux man page
A third way would be just to make one of the fixed arguments a literal count of the variable args.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Originally Posted by SalemSorry, I'm pretty new, and I don't understand how to do either of those. If it helps, I am trying to make my own max function. Just knowing how to do it will be useful.Originally Posted by manasij7479
Code:#include <iostream> #include <cstdarg> using namespace std; double smax(int num, ...) { va_list arg; int nmax=num; va_start (arg, num); while (!/*INSERT ENDLIST CHECK HERE*/) { if (nmax<va_arg(arg,double)) nmax=va_arg(arg,double); } va_end(arg); return nmax; } int main() { cout<<smax(1,2,3,4,5,0)<<endl; //suppost to show the maximum value as a string }
As mentioned, va_whatever doesn't give you any way to find the end of the list. You need to have your users tell you somehow where the end of the list is, either by telling you how many numbers there are, or by using some sentinel value at the end that you can check for.
The C++ way to do it, as also mentioned above, is to use a std::vector, which is an object that can be resized at will and that does know start and end. If you don't know anything about std::vector, then now is the time to start reading.
Here is an example...of that function..Originally Posted by GigaRoid
Code:template<class T> T my_max(std::vector<T> v) { T temp=v[0]; while(!v.empty()) { if(v.back()>temp) temp=v.back(); v.pop_back(); } return temp; }
Last edited by manasij7479; 08-28-2011 at 02:34 PM.
> cout<<smax(1,2,3,4,5,0)<<endl;
So does this zero mark the end of the va_list ?
The 3rd way I mentioned would call this function using.
cout<<smax(5,1,2,3,4,5)<<endl;
and inside the function, you would have
for ( i = 0 ; i < num ; i++ )
The first parameter is the count of the number of va_args.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
What way can I use this that doesn't give 5 errors?Originally Posted by mansij7479
Okay, that makes sense to me, but how do I check if the number of va_arg!=num instead of the value?Originally Posted by Salem
If you use it as given, you get 0 errors. If you are somehow getting 5 errors, then you will have to show us what you've done. (You are using a vector as it says, right? Not just putting a bunch of numbers inside parentheses?)
I don't know what you mean here, because we are checking the number of va_arg -- or at least, the number of arguments we told you to expect via the first parameter. Are you asking about a sentinel (i.e., the 0 in your example)? va_arg gives you the value of the variable, so you can check it that way.
Once again, I have no idea about this at all, so none of this is completely clear to me.Originally Posted by tabstop
So how would I check if the number of arguments is reached?va_arg gives you the value of the variable, so you can check it that way.
Last edited by GigaRoid; 08-28-2011 at 07:26 PM.
The number of variable arguments is num. num uses many different letters than va_arg (well, three anyway), so the compiler won't have much difficulty distinguishing them. (EDIT: This is assuming we're still talking about Salem's example and not gone somewhere completely different.)
Just to be clear: if you want the number of elements to be the first argument, Salem gave you exactly the code you need with no modification required. If you are looking for a sentinel value at the end (i.e., 0 ends the list), then you had that at the very beginning and didn't need to ask the question:
And actually you'd probably want to put do something like doing that va_arg call once into a variable, rather than three times, since we don't want to peel three arguments off the list every time.Code:while (va_arg(arg, double) != 0) if (nmax<va_arg(arg,double)) nmax=va_arg(arg,double);
Note that this code probably won't work with your call:
since those aren't doubles. You can't get away with that sort of type mismatch with va_arg lists.Code:smax(1,2,3,4,5,0)
I know it's possible for a function to know how many arguments there are without user input. To know how many arguments the loop has gone through you just use
The code just needs to know what mystery_num is. num!=argument_numbers. Or you could replace the 'argnum!=mystery_num' with 'va_arg(arg,double)!=empty_slot'. Checking if there is no value there. Or is it just stored as 0?Code:int argnum=1; //... while (argnum!=mystery_num) { if (nmax<va_arg(arg,double)) { nmax=va_arg(arg,double); argnum++; }
Last edited by GigaRoid; 08-29-2011 at 12:32 PM.