我想编写自己的lexical_cast
,在将double
转换为std::string
时会保留小数点。所以我正在使用ostringstream
并设置标记std::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
任何简单的方法?
答案 0 :(得分: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);
答案 1 :(得分: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);
,precision
为int
,x
为double
打印。对于我们得到的其他标志:
s.setf(std::ios::fixed); // %.*f
s.setf(std::ios::showpoint); // %#.*g
然而格式%#g
不仅保留小数点,还保留所有尾随零。该文档说明了#
与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的答案一样可能是最好的。