如何将浮点数0.1流式传输为.1而不是0.1

4
std::ostringstream oss;
oss << std::setw(10);
oss << std::setfill(' ');
oss << std::setprecision(3);
float value = .1;
oss << value

我可以检查数值是否小于1,然后找到前导零并将其移除。但这并不是非常优雅的解决方案。
2个回答

2
我可以检查值是否小于1,然后找到前导零并将其删除。这并不太优雅。 同意,但如果不在本地环境中混乱定义自己版本的ostream::operator<< (float),那么你只能这样做。(你不想混乱定义它。)
void float_without_leading_zero(float x, std::ostream &out) {
  std::ostringstream ss;
  ss.copyfmt(out);
  ss.width(0);
  ss << x;
  std::string s = ss.str();
  if (s.size() > 1 && s[0] == '0') {
    s.erase(0);
  }
  out << s;
}

1
哦,你可以使用“copyfmt”... 我猜每天都能学到新东西 :) +1 ...(每日投票限制,呃。) - Skurmedel
我不确定为什么我们要进行copyfmt,但我会再研究一下。谢谢!我假设我将我的oss变量传递到你的float_w/o..函数中,然后在那之后继续像往常一样使用它。 - John
1
@user506225:复制格式会复制精度和其他相关标志,但是宽度必须被排除(在此重置为零),以便获得预期的结果。是的,将您的流传递进来,这样它就可以将最终字符串写入其中,然后继续正常使用您的流。 - Fred Nurk

1
你可以编写自己的操作器。当然,优雅性是有争议的。不过它基本上会与你已经提出的相同。
例子:
struct myfloat
{
    myfloat(float n) : _n(n) {}

    float n() const { return _n; }

private:
    float _n;
};

std::ostream &<<(std::ostream &out, myfloat mf)
{
    if (mf.n() < 0f)
    {
        // Efficiency of this is solution is questionable :)
        std::ios_base::fmtflags flags = out.flags();
        std::ostringstream convert;
        convert.flags(flags);
        convert << mf.n();

        std::string result;
        convert >> result;

        if (result.length() > 1)
            return out << result.substr(1);
        else
            return out << result;
    }
    return out;
}

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