Reputation: 1687
I have a print function worked well, today I want add another parameter in this function, so I added it as first parameter, but all messages with extra parameters such as "%d", are all showing incorrectly, I searched for hours trying to understand why but got nothing useful, did I make anything wrong?
I tried to add "__cdecl", it didn't work either.
If I removed first parameter "int i", then everything is working properly. It's running on OS X 10.11 with Xcode 7.1.2 a console application.
void print(int i, const char* format_str, ...) {
// get parameters
va_list argptr;
char buffer[1024] = {0};
va_start(argptr, format_str);
vsprintf(buffer, format_str, argptr);
// log on screen
std::cout << (char*)buffer << std::endl;
va_end(argptr);
}
void call_print(const char* format_str, ...) {
print(1, format_str);
}
int main(int argc, const char * argv[]) {
// insert code here...
int test = 2;
call_print("test with %d", test);
// print(1, "test with %d", test);
return 0;
}
OK, I edited the code to make it run-able, it looks like the warped function is where the problem came out, how should I make it right??
If call print directly, it works properly, if using call_print, it will print "test with 1606416520", if removing the first parameter "int i", it works either....
Upvotes: 1
Views: 79
Reputation: 1687
It seems I have 2 ways to make it work, one is C++11's variadic template and according to my project's situation I choose second way which is simpler by moving va_start() to warp function call_print() then pass va_list to print(), finalized code would like this:
void print(int i, const char* format_str, va_list& argptr) {
char buffer[1024] = {0};
vsprintf(buffer, format_str, argptr);
// log on screen
std::cout << (char*)buffer << std::endl;
}
void call_print(const char* format_str, ...) {
// get parameters
va_list argptr;
va_start(argptr, format_str);
print(1, format_str, argptr);
va_end(argptr);
}
int main(int argc, const char * argv[]) {
// insert code here...
int test = 2;
call_print("test with %d", test);
// print(1, "test with %d", test);
return 0;
}
And using C++11's variadic template would like this, need add "-std=c++11" in other C++ flags:
void print(int i, const char* format_str, ...) {
// get parameters
va_list argptr;
char buffer[1024] = {0};
va_start(argptr, format_str);
vsprintf(buffer, format_str, argptr);
// log on screen
std::cout << (char*)buffer << std::endl;
va_end(argptr);
}
template< typename... Args >
void call_print(const char* format_str, Args... args) {
print(1, format_str, args...);
//std::snprintf( nullptr, 0, format_str, args... );
}
int main(int argc, const char * argv[]) {
// insert code here...
int test = 2;
call_print("test with %d", test);
//print(1, "test with %d", test);
return 0;
}
Upvotes: 0
Reputation: 7155
call_print
is not passing the parameter 'test' on to print
skip call_print
and call print
directly
Upvotes: 2