std::string formatting like sprintf

2018-12-31 14:19发布

I have to format std::string with sprintf and send it into file stream. How can I do this?

30条回答
柔情千种
2楼-- · 2018-12-31 14:31

Poco Foundation library has a very convenient format function, which supports std::string in both the format string and the values:

查看更多
与风俱净
3楼-- · 2018-12-31 14:33

boost::format() provides the functionality you want:

As from the Boost format libraries synopsis:

A format object is constructed from a format-string, and is then given arguments through repeated calls to operator%. Each of those arguments are then converted to strings, who are in turn combined into one string, according to the 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"
查看更多
呛了眼睛熬了心
4楼-- · 2018-12-31 14:33

You can format C++ output in cout using iomanip header file. Make sure that you include iomanip header file before you use any of the helper functions like setprecision, setfill etc.

Here is a code snippet I have used in the past to print the average waiting time in the vector, which I have "accumulated".

#include<iomanip>
#include<iostream>
#include<vector>
#include<numeric>

...

cout<< "Average waiting times for tasks is " << setprecision(4) << accumulate(all(waitingTimes), 0)/double(waitingTimes.size()) ;
cout << " and " << Q.size() << " tasks remaining" << endl;

Here is a brief description of how we can format C++ streams. http://www.cprogramming.com/tutorial/iomanip.html

查看更多
查无此人
5楼-- · 2018-12-31 14:34
inline void format(string& a_string, const char* fmt, ...)
{
    va_list vl;
    va_start(vl, fmt);
    int size = _vscprintf( fmt, vl );
    a_string.resize( ++size );
    vsnprintf_s((char*)a_string.data(), size, _TRUNCATE, fmt, vl);
    va_end(vl);
}
查看更多
妖精总统
6楼-- · 2018-12-31 14:34

Very-very simple solution.

std::string strBuf;
strBuf.resize(256);
int iCharsPrinted = sprintf_s((char *)strPath.c_str(), strPath.size(), ...);
strBuf.resize(iCharsPrinted);
查看更多
大哥的爱人
7楼-- · 2018-12-31 14:36

I gave it a try, with regular expressions. I implemented it for ints and const strings as an example, but you can add whatever other types (POD types but with pointers you can print anything).

#include <assert.h>
#include <cstdarg>

#include <string>
#include <sstream>
#include <regex>

static std::string
formatArg(std::string argDescr, va_list args) {
    std::stringstream ss;
    if (argDescr == "i") {
        int val = va_arg(args, int);
        ss << val;
        return ss.str();
    }
    if (argDescr == "s") {
        const char *val = va_arg(args, const char*);
        ss << val;
        return ss.str();
    }
    assert(0); //Not implemented
}

std::string format(std::string fmt, ...) {
    std::string result(fmt);
    va_list args;
    va_start(args, fmt);
    std::regex e("\\{([^\\{\\}]+)\\}");
    std::smatch m;
    while (std::regex_search(fmt, m, e)) {
        std::string formattedArg = formatArg(m[1].str(), args);
        fmt.replace(m.position(), m.length(), formattedArg);
    }
    va_end(args);
    return fmt;
}

Here is an example of use of it:

std::string formatted = format("I am {s} and I have {i} cats", "bob", 3);
std::cout << formatted << std::endl;

Output:

I am bob and I have 3 cats

查看更多
登录 后发表回答