stringstream:为什么“showpoint”会这样?行为类似于“固定”?

发布于 2024-11-14 04:05:49 字数 1143 浏览 6 评论 0原文

我想编写自己的 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 数字,这是我希望设置 < code>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

有什么简单的方法吗?

I'd like to write my own lexical_cast which preserves the decimal point when converting double to std::string. So I'm using ostringstream and set the flag 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;
}

This, however, prints unnecessary 0 digits, a behaviour I'd expect from setting std::ios::fixed but not std::ios::showpoint:

1.00000000000000
5.60000000000000
0.333333333333333

Without setting std::ios::showpoint it gives

1
5.6
0.333333333333333

but I want something like this:

1.0
5.6
0.333333333333333

Any easy way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

负佳期 2024-11-21 04:05:49

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

这可能不是最好的方法,但您可以将所有数字输出到 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);  

What you are wanting seems like a fairly custom behavior to me.

It may not the best way, but you can output all of the digits to your ostringstream, then search for the last non '0' character in the stream. Set the ending position of you stream to that position.

something along the lines of:

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);  
似梦非梦 2024-11-21 04:05:49

经过很长时间查看 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); 中所示,其中 precisionintx 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 的答案可能是最好的。

After a long time looking through the code of the std library it seems everything gets handed over to some printf type function: __builtin_vsnprintf(__out, __size, __fmt, __args). The format string __fmt is set depending on the flags set on the ostringstream object and can be queried using

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

The default format string is %.*g which is used as in printf("%.*g",precision,x); where precision is an int and x the double to be printed. For the other flags we get:

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

Yet the format %#g doesn't just keep the decimal point but also keeps all trailing zeros. The doc says about the usage of # combined with g:

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

Unfortunately, I can't find any other printf format string which behaves as nice as %g but always keeps the decimal point, so I guess something along the lines of dschaeffer's answer might well be the best.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文