如何在C++中为浮点值显示多个前导零?

Mik*_*nch 6 c++ double printf stream stringstream

在C++程序中,我想显示一列浮点值,以便符号,数字和小数点都排成一行.必要时,多个前导零应填充每个值的整数部分.例如:

A column of floating point values:
  +000.0012
  -000.0123
  +000.1235
  -001.2346
  +012.3457
  -123.4568
Run Code Online (Sandbox Code Playgroud)

我有一个精心评论的测试程序,证明了这个问题.但是,当我编辑这篇文章时,我在这里找到了我需要的答案:
- 使用printf打印浮点数时,额外的前导零?

基本的问题是我使用的格式代码"%+04.4f"应该使用"%+09.4f",因为我想要的总字段宽度为9:

  • 1为标志
  • 3为整数
  • 1表示小数点
  • 4为小数位数

我没有足够的声誉点来评论该帖子,所以谢谢你,@ AndiDog.

我仍然不知道如何使用流格式化标志获得多个前导零.但这是另一天的战斗.我现在会坚持使用printf和stream的混合物.

Jer*_*fin 9

一对夫妇的意见都提到std::setfill('0')和std::setw.虽然这些是必要的,但它们还不足以完成任务.例如,这段代码:

std::cout << std::setfill('0') << std::setw(7) << std::showpos << 0.012;
Run Code Online (Sandbox Code Playgroud)

将产生:0+0.012作为其输出.这显然不是我们想要的.

我们需要添加std::internal标志来告诉流插入"内部填充" - 即填充应该插入到符号和数字的其余部分之间,所以代码如下:

std::cout << std::setfill('0') << std::setw(7) << std::internal << std::showpos << 0.012;
Run Code Online (Sandbox Code Playgroud)

...产生我们想要的输出:+00.012.

另请注意,填充字符是"粘性的",因此如果您在使用std::setw数字和非数字类型之间交替使用,则可能需要/希望每次都更改它.否则,类似的东西std::cout << setw(12) << name;会产生如下结果:0000000Jerry这也很少需要.

为了确保我们总是在小数点后得到相同数量的位置,我们还需要设置std::fixed标志,并指定位数std::setprecision,例如:

#include <iostream>
#include <iomanip>
#include <vector>

int main() {
    std::vector<double> values { 0.1234, 1.234, 1.5555 };

    for (auto d : values)
        std::cout << std::internal << std::showpos << std::setw(9) 
                  << std::setprecision(3) << std::setfill('0') << d << "\n";
}
Run Code Online (Sandbox Code Playgroud)

这产生了我认为理想的输出:

+0000.123
+0001.234
+0001.556
Run Code Online (Sandbox Code Playgroud)

在某种情况下,您不会以这种方式获得对齐结果:如果您的数字太大而无法适应所提供的字段,则仍会打印小数点前的所有位置.例如,如果我们添加1e10到前面代码要打印的数字列表中,它将打印为:+10000000000.000,显然不会与其余代码对齐.

处理这种情况的显而易见的方法就是忍受它,如果它经常出现足够的关注,增加字段大小以适应更大的数字.

另一种可能性是使用固定符号,只有数字低于某个阈值,并切换到(例如)科学记数法以获得更大的数字.

至少根据我的经验,这样的代码往往主要用于财务数据,在这种情况下,后一种选择通常是不可接受的.