2

我想写我自己的,它在转换lexical_cast为时保留小数点。所以我正在使用并设置标志:doublestd::stringostringstreamstd::ios::showpoint

#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>

template <typename Source>
std::string my_string_cast(Source arg){
   std::ostringstream interpreter;
   interpreter.precision(std::numeric_limits<Source>::digits10);
   interpreter.setf(std::ios::showpoint);
   interpreter << arg;
   return interpreter.str();
}

int main(int argc, char** argv) {
   std::cout << my_string_cast(1.0) << std::endl;
   std::cout << my_string_cast(5.6) << std::endl;
   std::cout << my_string_cast(1.0/3.0) << std::endl;
   return 0;
}

但是,这会打印不必要的 0 数字,这是我期望设置std::ios::fixed但不是的行为std::ios::showpoint

1.00000000000000
5.60000000000000
0.333333333333333

没有设置std::ios::showpoint它给出

1
5.6
0.333333333333333

但我想要这样的东西:

1.0
5.6
0.333333333333333

有什么简单的方法吗?

4

2 回答 2

1

你想要的对我来说似乎是一种相当定制的行为。

这可能不是最好的方法,但您可以将所有数字输出到您的 ostringstream,然后在流中搜索最后一个非“0”字符。将流的结束位置设置为该位置。

类似于:

size_t endPos = interpreter.str().find_last_of("0");  
size_t begPos = interpreter.str().find_first_of(".") +2;  
if( endPos < begPos )  
  return interpreter.str().substr(0, begPos);  
else  
  return interpreter.str().substr(0, endPos);  
于 2011-06-03T19:22:35.307 回答
0

经过很长时间查看 std 库的代码后,似乎一切都交给了某个printf类型函数:__builtin_vsnprintf(__out, __size, __fmt, __args). 格式字符串__fmt是根据ostringstream对象上设置的标志设置的,可以使用查询

std::ostringstream s;
// ...
char format[50];
std::__num_base::_S_format_float(s,format,'\0');

默认格式字符串%.*g用作printf("%.*g",precision,x);where precisionis anint和要打印的xthe 。double对于我们得到的其他标志:

s.setf(std::ios::fixed);      // %.*f
s.setf(std::ios::showpoint);  // %#.*g

然而,该格式%#g不仅保留小数点,还保留所有尾随零。该文档说明了#组合 with的用法g

"printf" will always print out a decimal point and trailing zeros will not
be removed; usually 'g' and 'G' remove trailing zeros.

不幸的是,我找不到任何其他printf格式字符串表现得和小数点一样好,%g但总是保留小数点,所以我猜想 dschaeffer 的答案可能是最好的。

于 2011-06-05T09:16:51.817 回答