2011-06-03 21 views
1

我想写我自己的lexical_cast,它在将double转换为std::string时保留小数点。所以我使用ostringstream并设置标志std::ios::showpointstringstream:为什么“showpoint”的行为与“fixed”类似?

#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

后很长一段时间翻翻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);其中precisionintxdouble要被查询打印。对于其他的标志,我们得到:

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. 

不幸的是,我无法找到它的行为像你一样%g但始终保持小数点任何其他printf格式字符串,所以我想的东西沿dschaeffer的答案可能是最好的。

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); 
相关问题