fmt::format库故障?

3
#include <iostream>
#include <cstdint>
#include <fmt/core.h>

using namespace std;

int main(int argc, char **argv)
{
    cout<<"Expected: '       -10'\n      got:'"<<fmt::format("{:>10d}",-10)<<"'\n";
    cout<<"Expected: '-000000010'\n      got:'"<<fmt::format("{:>010d}",-10)<<"'\n";

    cout<<"Expected: '   -10.457'\n      got:'"<<fmt::format("{:>10.3f}",-10.456789)<<"'\n";
    cout<<"Expected: '-00010.457'\n      got:'"<<fmt::format("{:>010.3f}",-10.456789)<<"'\n";

    return 0;
}

上面的代码描述了我对格式库所期望的“有用”结果。 但实际输出却不同! 这只是库的一个错误,还是有任何相关原因来支持这个输出呢?
代码在这里:https://godbolt.org/z/YrxMr5x6x 输出取决于库的版本,即使是最新版本也会根据“我的个人喜好”出现故障(但我想你可能会有同感)。
以下是一些输出:
Expected: '       -10'
      got:'       -10' 
Expected: '-000000010'
      got:'0000000-10' 
Expected: '   -10.457'
      got:'   -10.457' 
Expected: '-00010.457'
      got:'000-10.457'

最新版本:
Expected: '       -10'
      got:'       -10'
Expected: '-000000010'
      got:'       -10'
Expected: '   -10.457'
      got:'   -10.457'
Expected: '-00010.457'
      got:'   -10.457'

1
这里没有问题:https://godbolt.org/z/asodq34Tz(除了你的第二个和最后一个期望是错误的...它会按照你的要求在-10前加上0) - Pepijn Kramer
很遗憾,fmt/std之间的格式说明符不同。 - Jarod42
@PepijnKramer 当我们请求在固定空间中填充0时,符号出现在末尾(我是从右到左创建数字的,所以我们先写最后一位数字,然后是前一位等等,如果我们要求在可用空间之前用0填充,应该在符号的右边)。0000-10是完全无用的,而上一个版本中选择的最后一个选项不能区分格式10.3f和010.3f。此外,我不明白你的评论,我访问了你提供的链接,库9.1.0给出了“意外”的输出,而10.0.0对于10.3f和010.3f没有任何区别。 - George Kourtis
我理解的方式是,格式前缀在左边使用的是“字符”,而不是数字。但是,毫无疑问,格式在不同版本之间的变化确实令人讨厌。 - Pepijn Kramer
1个回答

1
当指定对齐选项(<>^)时,0选项不起作用。只需移除>即可看到期望的输出。
这种行为是为了与std::format兼容。

[format.string.std]/8:

0 选项适用于除了 charTbool 的算术类型、指针类型,或者当指定整数表示类型时。

对于具有无限大或 NaN 以外值的格式化参数,该选项通过在符号或基本前缀指示器(如果有)之后插入0字符n来填充格式化参数。其中n为 0(如果存在align选项)且为填充宽度的其他情况。


逻辑上讲,如果要求填充,则对齐是无效的,因为完全填充的字段总是左对齐、右对齐或居中对齐。所以在这种情况下,< > ^ 可以被忽略,但不应改变行为...与行为出乎意料的东西的兼容性也是出乎意料的!(感谢你微妙的解释)。 - George Kourtis
1
这与std::format的兼容性关系较小,更多的是因为将0和对齐方式混合使用没有意义。 - vitaut

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