std::string and format string

20,706

Solution 1

You want to use the std::setprecision manipulator:

int main()
{
    std::cout << std::setprecision(9) << to_string<long>(3.1415926535897931, std::dec)
              << '\n';
    return 0;
}

Solution 2

C++ wouldn't be successful if it couldn't do something C could.

You need to check out manipulators.

If you want C-style formatting (which I do prefer, it's more terse), check out Boost.Format.

Solution 3

Have you looked at Boost::format?

Edit: It's not entirely clear what you want. If you just want to write to a string, with formatting, you can use normal manipulators on a stringstream. If you want to use printf-style formatting strings, but retain type-safety, Boost::format can/will do that.

Solution 4

Taking the almost-correct answer (note that std::dec is redundant in this simple case):

int main()
{
  std::cout << std::setprecision(9) << std::dec << 3.1415926535897931 << std::endl;
  return 0;
}

However, if you wanted the to_string function to behave as desired, that's a bit more difficult. You'd need to pass setprecision(9) to the to_string<T> function, and it doesn't accept arguments of that type. You'd want a templated version:

template <class T, class F>
std::string to_string(T t, F f)
{
  std::ostringstream oss;
  oss << f << t;
  return oss.str();
}
int main()
{
  std::cout << to_string<double>(3.1415926535897931, std::setprecision(9)) << std::endl;
  return 0;
}

This works because you really didn't need std::dec in to_string. But if you needed to pass more manipulators, the simple solution is to add template <class T, class F1, class F2> std::string to_string(T t, F1 f1, F2 f2) etcetera. Technically this doesn't scale very well, but it's going to be so rare that you probably don't need it at all.

Share:
20,706
Scott
Author by

Scott

Updated on August 28, 2020

Comments

  • Scott
    Scott over 3 years

    I found the below code through Google. It almost does what I want it to do, except it doesn't provide a way to indicate the precision like '%.*f' does in C-type format strings. Also, it doesn't provide anything further than 5 decimal places. Am I going to have to stick with C strings and snprintf?

    #include <string>
    #include <sstream>
    #include <iostream>
    
    template <class T>
    std::string to_string(T t, std::ios_base & (*f)(std::ios_base&))
    {
      std::ostringstream oss;
      oss << f << t;
      return oss.str();
    }
    
    int main()
    {
      std::cout<<to_string<double>(3.1415926535897931, std::dec)<<std::endl;
      return 0;
    }