Std :: String的C ++ Printf样式格式

时间:2014-04-29 10:10:37

标签: c++ string std

我正在编写一个实用程序函数来执行sprintf,就像基于Unicode设置的std :: string或std :: wstring一样。

#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重复传递给函数是否有任何问题。

1 个答案:

答案 0 :(得分:1)

sprintf_s替换为vsprintf(并删除尺寸)或vsprintf_s(如果有)。

从printf的联机帮助页引用。 (强调我的)

  

函数 vprintf(),vfprintf(),vsprintf(),vsnprintf()是   相当于函数 printf(),fprintf(),sprintf(),   snprintf(),分别用 va_list 调用它们   而不是可变数量的参数。这些功能不会调用   va_end宏。因为它们调用va_arg宏,其值为   通话结束后,ap未定义。