std::string formatting like sprintf

前端 未结 30 2916
野趣味
野趣味 2020-11-22 04:42

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

30条回答
  •  迷失自我
    2020-11-22 05:02

    [edit: 20/05/25] better still...:
    In header:

    // `say` prints the values
    // `says` returns a string instead of printing
    // `sayss` appends the values to it's first argument instead of printing
    // `sayerr` prints the values and returns `false` (useful for return statement fail-report)
    void PRINTSTRING(const std::string &s); //cater for GUI, terminal, whatever.. template void say(P...p) { std::string r{}; std::stringstream ss(""); (ss<<...< std::string says(P...p) { std::string r{}; std::stringstream ss(""); (ss<<...< void sayss(std::string &s, P...p) { std::string r{}; std::stringstream ss(""); (ss<<...< bool sayerr(P...p) { std::string r{}; std::stringstream ss("ERROR: "); (ss<<...<

    The PRINTSTRING(r)-function is to cater for GUI or terminal or any special output needs using #ifdef _some_flag_, the default is:

    void PRINTSTRING(const std::string &s) { std::cout << s << std::flush; }
    

    [edit '17/8/31] Adding a variadic templated version 'vtspf(..)':

    template const std::string type_to_string(const T &v)
    {
        std::ostringstream ss;
        ss << v;
        return ss.str();
    };
    
    template const T string_to_type(const std::string &str)
    {
        std::istringstream ss(str);
        T ret;
        ss >> ret;
        return ret;
    };
    
    template void vtspf_priv(std::string &s) {}
    
    template void vtspf_priv(std::string &s, H h, P...p)
    {
        s+=type_to_string(h);
        vtspf_priv(s, p...);
    }
    
    template std::string temp_vtspf(P...p)
    {
        std::string s("");
        vtspf_priv(s, p...);
        return s;
    }
    

    which is effectively a comma-delimited version (instead) of the sometimes hindering <<-operators, used like this:

    char chSpace=' ';
    double pi=3.1415;
    std::string sWorld="World", str_var;
    str_var = vtspf("Hello", ',', chSpace, sWorld, ", pi=", pi);
    


    [edit] Adapted to make use of the technique in Erik Aronesty's answer (above):

    #include 
    #include 
    #include 
    
    //=============================================================================
    void spf(std::string &s, const std::string fmt, ...)
    {
        int n, size=100;
        bool b=false;
        va_list marker;
    
        while (!b)
        {
            s.resize(size);
            va_start(marker, fmt);
            n = vsnprintf((char*)s.c_str(), size, fmt.c_str(), marker);
            va_end(marker);
            if ((n>0) && ((b=(n0) && ((b=(n

    [previous answer]
    A very late answer, but for those who, like me, do like the 'sprintf'-way: I've written and are using the following functions. If you like it, you can expand the %-options to more closely fit the sprintf ones; the ones in there currently are sufficient for my needs. You use stringf() and stringfappend() same as you would sprintf. Just remember that the parameters for ... must be POD types.

    //=============================================================================
    void DoFormatting(std::string& sF, const char* sformat, va_list marker)
    {
        char *s, ch=0;
        int n, i=0, m;
        long l;
        double d;
        std::string sf = sformat;
        std::stringstream ss;
    
        m = sf.length();
        while (i

提交回复
热议问题