This question already has answers here:
Count number of parameters in C variable argument method call
(4 answers)
Closed 7 years ago.
So in my function I want to take a variable number of char pointers.
void myFunction(char *_Name, ...);
Only, when I iterate through the arguments my code breaks because I'm not sure how to stop on the last argument I pass and not keep going.
void myClass::myFunction(char *_Name, ...)
{
char *a;
std::vector<char*> names;
va_list VariablePathList;
va_start (VariablePathList, _Name);
a = _Name;
bool exitLoop = false;
while(!exitLoop)
{
names.emplace_back(a);
a = va_arg(VariablePathList, char *);
//what must I do to set "exitLoop = true" at the right time?
}
va_end (VariablePathList);
}
Say I pass two char pointers into myFunction, then the code breaks on the third loop when va_arg is calling on unreadable memory.
Without telling myFunction how many agruments I have given it how can it find out the number to set exitLoop before the code breaks?
I can not seem to find straight forward information on how printf() and the like do this, so there could lie the solution I'm after.
Really, thank you in advance.
printf does it by parsing the format string. Some other functions do it by accepting an explicit count argument before the varargs. Which way to go will depend on your specific needs.
Really, though, it's 2015 now so you should be using variadic templates rather than archaic C customs. I also definitely do not advise storing char* in containers.
Here is all you need:
#include <vector>
#include <string>
template <typename... T>
void foo(T... args)
{
std::vector<std::string> names{args...};
// now use `names`
}
(live demo)
Related
How to pass multiple string parameter in C++ without using vector and pass it like an argument?
I want to do something like this.
void MyClass::go()
{
check("string1","string2","string3");
}
//guessing
void check(string values,...)
{
//how I can output each value here?
}
EDITED:
Thanks for the answers, but my goal is to pass string paramaters with undefine sizes. it means I don't need to input some int for it size. I don't want to use vectors :)
In my opinion the best solution would be to actually use a vector. This way you have type safety, and you can pass in any number of strings.
You can also use variadic templates.
If you exactly know how many strings you want to pass in, you can have a parameter list of that many strings. This is pretty tedious though, if you change your mind you need to rewrite your function (and every code using it).
The problem with var args is that it's not typesafe, the compiler can't verify, that you want to pass in a bunch of strings to your function.
void check (const string &string1, const string &string2, const string &string3)
{
cout << string1 << " " << string2 << " " << string3 << endl ;
}
In c & c++, this can be achieved by something called variable arguments. Note that for varargs, you do need to provide atleast one argument which is the number of strings, at the time of invoking the function.
A variable argument facilitates the passing of multiple arguments, without actually knowing the number of arguments to pass.
For this, you can include stdarg.h. This gives you the data type: va_list, and associated functions:
#include <cstdarg>
#include <iostream>
using namespace std;
void check ( int num, ... )
{
va_list arguments; //a place to store the arguments values
va_start ( arguments, num ); // Initializing arguments to store all values after num
for ( int x = 0; x < num; x++ ) { // Loop until all numbers are added
cout << va_arg ( arguments, string ); // Prints the next value in argument list to sum.
}
va_end ( arguments ); // Cleans up the list
}
void MyClass::go()
{
check(3,"string1","string2","string3");
}
num is the number of arguments, that you'll provide.
va_start populates the va_list with the arguments (in this case the strings) that you provide.
va_arg() is used as to access those arguments in the list.
Finally, va_end() is used for cleaning up the va_list.
Either you may use va_list or variadic templates in C++11. It depends on your context.
This question already has answers here:
Variable number of arguments in C++?
(17 answers)
Closed 9 years ago.
I currently have
std::stringstream ss;
ss << "hey"<<" "<< "hey"<<" "<< "hey"<<" "....// here I want to be able to pass different kinds of messages
std::string s(ss.str());
write(to_chat_message(s));
I want to convert the part before write to a function so that I can simply do write(to_chat_message("hey"," ","hey"," ","hey"," ",...));
How should I write this new overloaded to_chat_message() method
If you're only taking in strings, just use a vector of strings. Parse over the vector in the method. Based on your question there doesn't appear to be a need for variable arguments.
Since you obviously only want strings and char-arrays that are convertible to strings, you will only need a variable number of string arguments.
The first thing that comes to mind is std::vector.
std::string to_chat_message(std::vector<std::string> v) {
//do something with the strings in v...
}
in C++11
this can be very easily done together with initializer-lists:
//...
string str{"meh"};
write(to_chat_message({"hey", " ", "hey", str, "what?"}));
For convenience, to get rid of the curly braces, you could write a variadic template:
template <class... Args>
std::string to_chat_message(Args&&... args) {
return to_chat_message({ std::forward<Args>(args)... });
}
// and now...
write(to_chat_message("hey", " ", "hey", str, "what?"));
in C++03
you have neither variadic templates nor initializer-lists. But you have boost.assign:
#include <boost/assign/list_of.hpp>
using boost::assign::list_of;
write(to_chat_message(list_of<std::string>("hey")(" ")("hey")(str)("what?")));
Thats a bot more verbose, so you could roll a convenience function, but that would have to rely on boosts detail implementation of list_of:
boost::assign::assign_detail::generic_list<std::string> sl(std::string const& str)
{ return boost::assign::list_of(str); }
write(to_chat_message(sl("hey")(" ")("hey")(str)("what?")));
Or you roll your very own implementation, just for this purpose:
struct ToChatMessage {
std::vector<std::string> strings;
ToChatMessage(std::string const& str) {strings.push_back(str);}
operator std::string() const { return to_chat_message(strings); }
ToChatMessage& operator()(std::string const& str) {
strings.push_back(str);
return *this;
}
};
write(ToChatMessage("hey")(" ")("hey")(str)("what?"));
This does mostly what list_of does: with the leftmost call (constructor) you create an object that holds a vector of strings and push the first argument into that vector. The other calls (operator()) push more values into the vector. You can chain thise calls because the operator() returns a reference to the object. Finally, since write() accepts only strings and not objects of type ToChatMessage, that object is converted into a string by calling operator string() and thus passing the vector of strings to to_chat_message.
Instead of overloading operator() you could of course use other operators, depending on what you'd like the call to look like, e.g. operator<<:
write(ToChatMessage() << "hey" << " " << "hey" << str << "what?" );
Of course there is the possibility to overload to_chat_message with accepting one through N arguments, but that would mean you'd either have to repeat mostly the same stuff manually N times, your you would ahve to use preprocessor magic like Boost.Preprocessor and create an unreadable, hard to maintain and nondebuggable mess defininig all those overloads.
You will need to use the standard C/C++ method of passing a variable number of parameters to a function. As Shafik mentioned you should look at "Variable Number of Arguments in C" The accepted answer should have all of the information that you need to do this.
I have been reading that some compilers support va_list with macros and users were able to overload the functionality with other macros in order to count the va_list.
With visual studio, is there a way to determine if the va_list is empty (aka count==0)? Basically I would like to know this condition:
extern void Foo(const char* psz, ...);
void Test()
{
Foo("My String"); // No params were passed
}
My initial thought was to do something like this:
va_list vaStart;
va_list vaEnd;
va_start(vaStart, psz);
va_end(vaEnd);
if (vaStart == vaEnd) ...
The problem is that va_end only sets the param to null.
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap) ( ap = (va_list)0 )
I was thinking of maybe incorporating a terminator but I would want it to be hidden from the caller so that existing code doesnt need to be changed.
There is no way to tell how many arguments are passed through ..., nor what type they are. Variadic function parameters can only be used if you have some other way (e.g. a printf-style format string) to tell the function what to expect; and even then there is no way to validate the arguments.
C++11 provides type-safe variadic templates. I don't know whether your compiler supports these, or whether they would be appropriate for your problem.
I realize this question is fairly old, but I thought it might be helpful to flesh it out a bit. As Mike Seymour answered quite correctly, there is no absolutely reliable way to determine the number of arguments in a va_list. That's why the conventional way to define a variadic function is to include a parameter that has that information, like so: void func(const char *str, int count, ...);, which defines a contract your callers are supposed to abide by.
EDIT: The standard (7.16.1.1.3) is actually silent on the value returned by va_arg(vl, type) for any call past the end of the variable argument list. The most common case for most types is typed-zero. However, CAVEAT EMPTOR - it doesn't have to be.
The value returned from va_arg(vl, type) when there are no more arguments is a typed-zero value. For numeric types, it is 0. For pointers, it is a NULL pointer. For structs, it is a struct with all fields zeroed. If you elect to copy the va_list and try to count the copy, like so:
void func(const char *str, ...) {
va_list vl;
va_list vc;
int x;
int count;
count = 0;
va_start(vl, str);
va_copy(vc, vl);
do {
x = va_arg(vc, int);
if (x == 0) break;
count++;
} while (1)
va_end(vc);
.
.
. // do something, or something else,
. // based on the number of args in the list
.
va_end(vl);
You would have to make the assumption that the caller would abide by the contract not to pass a NULL or zero value in the list. Either way, you have to understand that the caller of a variadic function is responsible for abiding by the stated contract. So write your function, publish the contract, and sleep easy.
I am aware that my answer isn't an "orthodox" answer, however due to the limitation of the va_list macro, I found the following solution to work. We can look at a va_list as an array of chars, and even better, a null terminated one, so you can try
va_list argptr;
if(strcmp(argptr,""))
{
// not empty
}
else
{
// empty
}
I tried that and it worked for me.
I used Visual Studio 2013 Ultimate. The project type is Win32 Console Application. No compilation errors.
I have a function with following signature
char requestApiCall(int num, const wchar_t* pParams = 0, ...)
{
...
}
Now I want to to get all pParams in an array (or to be able to iterate over it). I know this is possible with some macros, but I have no idea how to do it.
Any help would be appreciated.
P.S. I'm using MinGW if it matters.
UPDATE
my question caused confusion. I will try to clarify (sorry for my grammar). Both Object Pascal and C# has the ability to pass unlimited amount of parameters to a method. In C# we achieve this with params keyword:
void Foo(params string[] strs)
{
...
}
Foo("first", "second", "another one", "etc");
I want to achieve same result in C++ without using any object/class. In my case, type safety is not a concern, but if there is a type safe way to achieve that goal, I will gladly hear your comments :)
Thanks
You need to look at the functions and macros declared in stdarg.h. Here is a tutorial that explains it.
http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html
I'm not sure what your function parameters are supposed to represent but I think you'll find that it needs to change.
By the way, I find that for C++ I can usually avoid variadic functions. This has the advantage of preserving type safety. Are you sure you really need a variadic function?
Using variadic function arguments is a dangerous and tricky business, and almost surely there is a better way - for example, you might pass an std::vector<std::wstring>& to your function!
OK, that said, here's how to use variadic arguments. The key point is that it is your responsibility to know the number and types of the arguments!
#include <cstdarg>
char requestApiCall(int num, const wchar_t* pParams, ...)
{
va_list ap; // the argument pointer
va_start(ap, pParams); // initialize it with the right-most named parameter
/** Perform magic -- YOU have to know how many arguments you are getting! **/
int a = va_arg(ap, int); // extract one int
double d = va_arg(ap, double) // one double
char * s = va_arg(ap, char*) // one char*
/* ... and so forth ... */
va_end(ap); // all done, clean up
}
Just for completeness, I would redefine the function as this:
char requestApiCall(std::vector<std::wstring> & params)
{
for (std::vector<std::wstring>::const_iterator it = params.begin(), end = params.end(); it != end; ++it)
{
// do something with *it
}
/* ... */
}
A good example of what you are trying to accomplish is the exec family of functions. exec() takes an variable list of arguments all of which are expected to be const char*. The last item is a NULL ((char*)0). The last item is the indicator for when the list of items is complete.
You can use the variadic macros in stdargs.h as others have described.
I have to classes, an Executer with these methods:
Executer()
struct Execute(string s)
Lookup(string name, int module, int num, ...)
and a Parser:
Parser()
struct Parse(string s)
The Exectuers Execute method calls the Parsers Parse method. The Parser then chucks the string into smaller bits (it explodes the string on the ;-sign) and returns a struct to the Execute method. This struct it uses to call the Lookup method.
The struct that the Parse returns holds some standard information:
An command name
A senderId (a username, a mac address and a password)
A variable number of arguments
And that is my problem. The Lookup method take variable arguments, but how do I handle the the hand over of these variable arguments by the struct? Im not an expert in C and C++. Should I mass the two classes togheter? So the Parser method could call the Execute method, sparing the struct away.
Or maybe there is a way of parsing an unknown variable of arguments at runtime? By some sort of array?
EDIT
I cant use the STL library from C++. I only use the C++ class and virtual feature. Im writing to an compiler where Im restricted to use almost all of the C libraries + the magic skills of C++ (virtual and class). SOory for not telling that right away.
EDIT 2
Im writing code to an embedded system and thereby using avr-gcc to compile my code. Thats why I cant use STL. The avr-gcc doesnt support this.
Use std::vector<> or a simular container that can hold an arbitrary number of entries.
struct {
std::string commandName;
sender_t senderId;
std::vector<arg_t> arguments;
};
Edit: oh, you can't use std::vector. In that case: use an array and store the length:
struct {
const char* commandName;
sender_t senderId;
int argumentCount;
int maxArgumentCount; // you might not need this
arg_t* arguments; // pointer to array of (at least) argumentCount elements.
};
Use malloc() or new() to create the array for the arguments.
I would suggest to wrap the argumentCount, maxArgumentCount and arguments in a separate class, which can handle the malloc/new and free/delete as well. This will make it easier to prevent memory leaks.
In the end, you'll have written your own vector_of_arg_t class, so maybe have a look at some basic vector implementation. There must be tutorials on that on the web.
You could declare your Lookup method as follows:
void Lookup(string name, int module, int num, std::vector<std::string> &args);
By storing the variable arguments in an args array, you can have as many as you want.
See
Q: How can I write a function which takes a variable number of arguments and passes them to some other function (which takes a variable number of arguments)?
A: In general, you cannot. Ideally, you should provide a version of that other function which accepts a va_list pointer.
Suppose you want to write a faterror function which will print a fatal error message, then exit. You might like to write it in terms of the error function of question 15.5:
void faterror(const char *fmt, ...)
{
error(fmt, what goes here? );
exit(EXIT_FAILURE);
}
but it's not obvious how to hand faterror's arguments off to error.
<snip>
Read on at
http://c-faq.com/varargs/handoff.html