4

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;
} 

4 Answers 4

2

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

That's not going to work actually. You're applying the manipulator to std::cout but pi is formatted inside to_string<long>(long t). Furthermore, since you passed pi as a long, it becomes 3L.
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.

Comments

1

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.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.