0

std::stringC++ WinAPI アプリケーションでC 文字列と sa を少し簡単に結合する関数を作成しようとしています。

したがって、これを行う代わりに:

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(); パラメータ形式内で複数の変数を渡すと失敗し、その理由がわかりませんか?

// 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 を押してプログラムをデバッグするか、Continue を押してプログラムを終了します。

詳細については、ヘルプ トピック「バッファ オーバーランの問題をデバッグする方法」を参照してください。

4

1 に答える 1

1

可変引数の処理が少しずれているようです。はい、固定サイズのバッファに書き込むことで、スタック オーバーフローを要求しています。

最初のものを修正するには、可変引数を受け入れるバージョンの 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]);
}
于 2012-05-13T05:29:32.417 に答える