标准::字符串的C++打印样式格式
C++ Printf Style Formatting for Std::String
我正在编写一个实用函数,根据Unicode设置对std::string或std::wstring进行类似sprintf的格式化。
#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 ;
}
调用时类似:
int iId = 2 ;
MyString strFileName = Utils::GetStringPrintf(MYTEXT("Student_%d.png"), iId) ;
//对于Unicode,我正在Student_1633600.png而非Student_2.png//对于非Unicode,我得到Student_1633800.png而非Student_2.png
在调试时,我确实得到iVal的值为2,但不知何故,这些值在传递给sprintf时变得很糟糕。
但是,如果我打电话,直接sprintf,
MyChar szFilename[200] ;
int iId = 2 ;
_stprintf_s(szFilename, 200, MYTEXT("Student_%d.png"), iId) ;
我得到了正确的输出,即Student_2.png
我确实参考了Stack Overflow中关于sprintf功能的其他帖子,发现我的代码与这些帖子非常相似。将va_list重复传递给函数有问题吗。
将sprintf_s
替换为vsprintf
(并删除大小)或vsprintf_s
(如果可用)。
引用自printf的手册页。(强调矿)
函数vprintf()、vfprintf()、vsprintf(相当于函数printf(),fprintf(),sprintf(),snprintf(),不同之处在于它们是用va_list调用的而不是可变数量的参数。这些函数不调用va_end宏。因为它们调用了va_arg宏ap在调用后未定义。