2

我通过谷歌找到了下面的代码。它几乎完成了我想要它做的事情,除了它没有提供一种方法来指示精度,就像 '%.*f' 在 C 类型格式字符串中所做的那样。此外,它不提供任何超过小数点后 5 位的内容。我将不得不坚持使用 C 字符串和 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

4 回答 4

2

如果 C++ 不能做 C 能做的事情,它就不会成功。

您需要检查操纵器

如果您想要 C 风格的格式(我更喜欢它,它更简洁),请查看Boost.Format

于 2009-10-15T23:42:35.800 回答
2

您想使用std::setprecision操纵器:

int main()
{
    std::cout << std::setprecision(9) << to_string<long>(3.1415926535897931, std::dec)
              << '\n';
    return 0;
}
于 2009-10-15T23:43:33.083 回答
1

你看过Boost::format吗?

编辑:你想要什么并不完全清楚。如果您只想写入带有格式的字符串,则可以在字符串流上使用普通操纵器。如果你想使用 printf 风格的格式化字符串,但保留类型安全,Boost::format 可以/将会这样做。

于 2009-10-15T23:42:43.227 回答
1

采取几乎正确的答案(注意 std::dec 在这种简单情况下是多余的):

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

但是,如果您希望 to_string 函数按预期运行,那就有点困难了。您需要传递setprecision(9)给该to_string<T>函数,并且它不接受该类型的参数。您需要一个模板版本:

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

这是有效的,因为您在 to_string 中确实不需要 std::dec。但是如果你需要传递更多的操纵器,简单的解决方案是添加template <class T, class F1, class F2> std::string to_string(T t, F1 f1, F2 f2)等等。从技术上讲,这不能很好地扩展,但它会非常罕见,你可能根本不需要它。

于 2009-10-16T08:02:49.130 回答