我正在尝试创建一个函数,使C Strings和std::string
在我的C ++ WinAPI应用程序中更容易结合。
所以不要这样做:
TCHAR res[MAX_PATH];
_stprintf(res, _T("In functionX(): error occured where the variable values are %d, %u, %s, %c"), myInt, myUnsignedInt, myStr.c_str(), myChar);
MessageBox(NULL, res, _T("Error Occurred"), MB_OK);
我必须这样做(这使得合并不同的字符串类型更容易一些,因为我不必在任何地方继续声明TCHAR数组):
tstring res = concat(_T("In functionX(): error occured with the variable values %d, %u, %s, %c"), myInt, myUnsignedInt, myStr.c_str(), myChar);
MessageBox(NULL, (LPTSTR)res.c_str(), _T("Error Occurred"), MB_OK);
我的问题:我的函数 concat(); 在参数 format 中传递多个变量时失败,我不知道为什么?
// The following function call causes the error
tstring ou = concat(_T("In functionX(): Failed to create temp file - %s - %s\r\n"), (LPTSTR)tempFileRootDir.c_str(), tempFile);
tstring WinFile::concat( TCHAR* strFormat, TCHAR* format, ... )
{
// tstring is either a std::string or std::wstring depending on whether unicode is used
// Post: Wrapper function to easily merge C++ strings with C Strings
va_list arguments;
va_start(arguments, format);
TCHAR res[MAX_PATH];
_stprintf(res, strFormat, format);
return tstring(res);
}
在Microsoft Visual C ++中运行该函数时发生的错误是:
Application.exe中发生缓冲区溢出 破坏了程序的内部状态。按Break打开调试 程序或继续终止程序。
有关详细信息,请参阅帮助主题“如何调试缓冲区溢出” 问题。
答案 0 :(得分:1)
看起来你的varargs处理有点过时了。是的,通过写入固定大小的缓冲区,您需要堆栈溢出。
要纠正第一个,您需要使用varargs接受版本的printf。对于第二个,你应该在打印之前计算:
tstring WinFile::concat( TCHAR const * strFormat, ... )
{
va_list args;
// Determine how much space to reserve.
va_start(args, strFormat);
size_t msg_len=_vsctprintf(strFormat, args);
va_end(args);
// Reserve space on heap.
//
// "_vscprintf returns the number of characters that would be generated
// if the string pointed to by the list of arguments was printed ...
// [and] does not include the terminating null character."
//
// So we add space for a terminating null.
std::vector<TCHAR> writebuffer(1+msg_len);
// perform formatting
va_start(args, strFormat);
_vstprintf(&writebuffer[0], strFormat, args);
va_end(args);
// return a copy as a tstring.
return tstring(&writebuffer[0], &writebuffer[msg_len]);
}