我必须用sprintf格式化std::string,并将其发送到文件流。我该怎么做呢?


当前回答

对于Visual C:

std::wstring stringFormat(const wchar_t* fmt, ...)
{
    if (!fmt) {
        return L"";
    }

    std::vector<wchar_t> buff;
    size_t size = wcslen(fmt) * 2;
    buff.resize(size);
    va_list ap;
    va_start(ap, fmt);
    while (true) {
        int ret = _vsnwprintf_s(buff.data(), size, _TRUNCATE, fmt, ap);
        if (ret != -1)
            break;
        else {
            size *= 2;
            buff.resize(size);
        }
    }
    va_end(ap);
    return std::wstring(buff.data());
}

其他回答

Boost::format()提供了你想要的功能:

Boost格式库简介如下:

format对象由format-string构造,然后通过反复调用运算符%来给出参数。 然后,每个参数都被转换为字符串,这些字符串又根据format-string组合成一个字符串。

#include <boost/format.hpp>

cout << boost::format("writing %1%,  x=%2% : %3%-th try") % "toto" % 40.23 % 50; 
// prints "writing toto,  x=40.230 : 50-th try"

以下是我的(简单的解决方案):

std::string Format(const char* lpszFormat, ...)
{
    // Warning : "vsnprintf" crashes with an access violation
    // exception if lpszFormat is not a "const char*" (for example, const string&)

    size_t  nSize     = 1024;
    char    *lpBuffer = (char*)malloc(nSize);

    va_list lpParams;

    while (true)
    {
        va_start(lpParams, lpszFormat);

        int nResult = vsnprintf(
            lpBuffer,
            nSize,
            lpszFormat,
            lpParams
        );

        va_end(lpParams);

        if ((nResult >= 0) && (nResult < (int)nSize) )
        {
            // Success

            lpBuffer[nResult] = '\0';
            std::string sResult(lpBuffer);

            free (lpBuffer);

            return sResult;
        }
        else
        {
            // Increase buffer

            nSize =
                  (nResult < 0)
                ? nSize *= 2
                : (nResult + 1)
            ;

            lpBuffer = (char *)realloc(lpBuffer, nSize);
        }
    }
}

根据Erik Aronesty提供的答案:

std::string string_format(const std::string &fmt, ...) {
    std::vector<char> str(100,'\0');
    va_list ap;
    while (1) {
        va_start(ap, fmt);
        auto n = vsnprintf(str.data(), str.size(), fmt.c_str(), ap);
        va_end(ap);
        if ((n > -1) && (size_t(n) < str.size())) {
            return str.data();
        }
        if (n > -1)
            str.resize( n + 1 );
        else
            str.resize( str.size() * 2);
    }
    return str.data();
}

这避免了需要从原始答案中的.c_str()结果中取消const。

template<typename... Args>
std::string string_format(const char* fmt, Args... args)
{
    size_t size = snprintf(nullptr, 0, fmt, args...);
    std::string buf;
    buf.reserve(size + 1);
    buf.resize(size);
    snprintf(&buf[0], size + 1, fmt, args...);
    return buf;
}

使用C99 snprintf和c++ 11

_return.desc = (boost::format("fail to detect. cv_result = %d") % st_result).str();