std::string和格式化字符串

4

我通过谷歌找到了以下代码。它几乎实现了我的要求,但它没有提供像C类型格式字符串中'%.*f'一样指定精度的方法。而且,它最多只能提供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个回答

2
你想要使用 std::setprecision 操纵符:
int main()
{
    std::cout << std::setprecision(9) << to_string<long>(3.1415926535897931, std::dec)
              << '\n';
    return 0;
}

4
实际上那样做是行不通的。你将操作器应用于 std::cout,但 pi 在 to_string<long>(long t) 中被格式化。此外,由于你将 pi 作为 long 传递,它变成了 3L - MSalters

2

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

你需要查看操作符

如果你想要C风格的格式化(我更喜欢这种方式,更简洁),请查看Boost.Format


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)等等。从技术上讲,这种方法并不很可扩展,但它很少用到,你可能根本不需要它。

1
你看过Boost::format吗?
编辑:不太清楚你想要什么。如果你只是想要将格式化的内容写入字符串,可以在stringstream上使用普通的操作符。如果你想要使用printf风格的格式化字符串,但又想保持类型安全,那么可以使用Boost::format。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接