I'm trying to create a function that takes a variable amount of std::string arguments and formats a string with it.
Example:
Test::formatLine(const string::format, ...)
{
const std::string buffer;
va_list args;
va_start(args, format);
vsprintf(buffer.c_str, format.c_str, args);
va_end(args);
cout << buffer << endl;
}
Compiling this snippet errors:
Error 1 error C3867: 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str': function call missing argument list; use '&std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str' to create a pointer to member
What I want to achieve:
Test t = Test();
t.formatLine("Hello %s!", "monsieur");
should print Hello monsieur!
t.formatLine("Hello %s %s! How %s you today?", "good", "sir", "are");
should print Hello good sir! How are you today?
Is it even possible to use va_list
and vsprintf
with std::string
only, avoiding char buffer[size]
?
Working example (so far) with fixes suggested by Igor, using buffer:
void Test::formatLine(string format, ...)
{
char buffer[256];
va_list args;
va_start(args, format);
vsprintf_s(buffer, format.c_str(), args);
va_end(args);
cout << buffer << endl;
}
Using Igor Tandetnik's suggestion and sample code I finally got a working example that does not use char buffer[size]:
void Test::formatLine(string format, ...)
{
vector<char> buf(256);
va_list args;
va_start(args, format);
vsnprintf_s(&buf[0], buf.size(), buf.size() + strlen(format.c_str()), format.c_str(), args);
va_end(args);
cout << &buf[0] << endl;
}
First, it's buffer.c_str()
and format.c_str()
(note the parentheses).
Second, the first parameter of vsprintf
should be a modifiable buffer of sufficient size. You are trying to pass a const char*
pointing to a buffer just one byte large.
You could use vector<char>
as a buffer holder (it's easy to resize). The problem is, there's no way to get the required buffer size out of vsprintf
. One technique is to allocate some initial buffer, then call vsnprintf
(note the 'n') repeatedly, doubling the size of the buffer every time the function says it's too small.