标准::字符串的C++打印样式格式

C++ Printf Style Formatting for Std::String

本文关键字:样式 格式 打印 字符串 标准 C++      更新时间:2023-10-16

我正在编写一个实用函数,根据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在调用后未定义。