Reputation: 63
I was writing a utility function to do sprintf like formatting for std::string or std::wstring based on Unicode settings.
#ifdef _UNICODE
typedef std::wstring MyString ;
typedef TCHAR MyChar ;
#define MYTEXT TEXT
#else
typedef std::string MyString ;
typedef char MyChar ;
#define MYTEXT
#endif //_UNICODE
MyString Utils::GetStringPrintf(const MyString kstrText, ...)
{
int iCharsWritten = 0 ;
MyString strFinal ;
MyChar szBufferTouse[8194] ; //Hopefully Long enough
va_list fmtList ;
va_start(fmtList, kstrText) ;
/*int iVal = va_arg(fmtList, int) ;*/ =>Just for debugging
#ifdef _UNICODE
iCharsWritten = _stprintf_s(szBufferTouse, 8194, kstrText.c_str(), fmtList) ;
#else
iCharsWritten = sprintf_s(szBufferTouse, 8194, kstrText.c_str(), fmtList) ;
#endif //_UNICODE
va_end(fmtList) ;
strFinal = szBufferTouse ;
return strFinal ;
}
When called like :
int iId = 2 ;
MyString strFileName = Utils::GetStringPrintf(MYTEXT("Student_%d.png"), iId) ;
//For Unicode am getting Student_1633600.png instead of Student_2.png //For non-Unicode am getting Student_1633800.png instead of Student_2.png
Upon debugging I do get the value of iVal as 2, but somehow the values get bad upon passing to sprintf.
However if I call, sprintf directly,
MyChar szFilename[200] ;
int iId = 2 ;
_stprintf_s(szFilename, 200, MYTEXT("Student_%d.png"), iId) ;
Am getting proper output, i.e Student_2.png
I did refer other posts in Stack Overflow regarding sprintf functionality and found my code to be doing quite similar to those. Is there any problem in passing va_list repeatedly to functions.
Upvotes: 1
Views: 714
Reputation: 30489
Replace sprintf_s
with vsprintf
(and remove size) or with vsprintf_s
if available.
Quoting from manpage of printf. (Emphasis mine)
The functions vprintf(), vfprintf(), vsprintf(), vsnprintf() are equivalent to the functions printf(), fprintf(), sprintf(), snprintf(), respectively, except that they are called with a va_list instead of a variable number of arguments. These functions do not call the va_end macro. Because they invoke the va_arg macro, the value of ap is undefined after the call.
Upvotes: 1