gpt4 book ai didi

c++ - std::showbase 和 std::showpos 是否互斥?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:41:18 26 4
gpt4 key购买 nike

这个问题源于我关于使用通常的 ostream & operator << (ostream &, some_type) 输出数值的正确方法的讨论。对于 C++ 中的数字类型。

我熟悉每个基数中 std::showbase 和 std::showpos 的行为,它们基本上是互斥的。即:十进制不显示底数,正数加'+';而在十六进制或八进制中,会显示基数,但不会显示“+”(也不会显示负号),因为打印的类型值就好像它被转换为无符号类型一样。

例如,这个简单(冗长)的程序:

#include <iostream>

int main() {
std::cout << std::dec << std::showpos << std::showbase << int64_t(+5) << std::endl;
std::cout << std::oct << std::showpos << std::showbase << int64_t(+5) << std::endl;
std::cout << std::hex << std::showpos << std::showbase << int64_t(+5) << std::endl;
std::cout << std::dec << std::showpos << std::showbase << int64_t(-5) << std::endl;
std::cout << std::oct << std::showpos << std::showbase << int64_t(-5) << std::endl;
std::cout << std::hex << std::showpos << std::showbase << int64_t(-5) << std::endl;
}

使用 GCC 编译时给出此输出:

+5
05
0x5
-5
01777777777777777777773
0xfffffffffffffffb

这是我一直期望的,使用 C++ 多年,但标准真的保证了这一点,还是这只是常见的行为?例如,符合标准的 C++ 编译器是否可以输出这些序列之一?

+5
+05
+0x5
-5
01777777777777777777773
0xfffffffffffffffb

甚至:

+5
+05
+0x5
-5
-05
-0x5

最佳答案

对于 ios_base本身,不。 showposshowbase调用单参数 setf (§27.5.6.1[fmtflags.manip]/5 and/13) on the stream,两者互不影响。


再深入一点,一个 std::ostream使用 locale::facet::put打印整数的函数 (§27.7.3.6.2[ostream.inserters.arithmetic]/1),及其实现 locale::facet::do_put(§22.4.2.2.2[facet.num.put.virtuals]/5) 指定:

All tables used in describing stage 1 are ordered. That is, the first line whose condition is true applies. A line without a condition is the default behavior when none of the earlier lines apply.

...

The conversion specifier has the following optional additional qualifiers prepended as indicated in Table 90.

                  Table 90 — Numeric conversions+-----------------------+-------------------+------------------+| Type(s)               | State             | stdio equivalent |+=======================+===================+==================+|                       | flags & showpos   | +                || an integral type      |                   |                  ||                       | flags & showbase  | #                |+-----------------------+-------------------+------------------+|                       | flags & showpos   | +                || a floating-point type |                   |                  ||                       | flags & showpoint | #                |+-----------------------+-------------------+------------------+

...

The representations at the end of stage 1 consists of the char’s that would be printed by a call of printf(s, val) where s is the conversion specifier determined above.

在这里,我们看到 showposshowbase在同一个单元格中,我相信标准隐含地意味着它们在同一“行”中,因此 both 适用(从 std::cout << std::showpos << std::showpoint << 6.0 可以看出以下“行” "), 这两个标志在这里仍然不相互排斥。


到目前为止,我们看到 showposshowbase在 C++ 中不是独占的,实际的格式化行为由 printf 定义(虽然实现不需要使用 printf ,例如 libc++ 使用 sprintf ,而 libstdc++ 不需要),我们必须检查 C 标准。

在 C 中,使用 + ( showpos ) 和 ox/X ( octhex )没有定义,因为 C99 §7.19.6.1/6 和/8 说

+

The result of a signed conversion always begins with a plus or minus sign. ...

o , u , x , X

The unsigned int argument is converted to ...

参数未签名,所以 +不能申请。该行为未写出,因此未定义。

添加# ( showbase ) 到 d ( dec ) 也是未定义的行为,如子句/6 所说:

#

The result is converted to an “alternative form”. For o conversion, ... For x (or X) conversion, ... For a, A, e, E, f, F, g, and G conversions, ... For g and G conversions, ... For other conversions, the behavior is undefined.

糟糕。

因此,不仅两个标志不互斥,输出也根本没有定义。提到的场景 2 和 3 OP 可能会发生。在 gcc 和 clang 中,冲突的选项( showpos 代表 octhexshowbase 代表 dec )被简单地忽略,这给人一种这两个选项相互排斥的错觉,但标准将不能保证。

(免责声明:我使用的是 n3242 和 n1124 作为引用,最终标准可能不完全相同)

关于c++ - std::showbase 和 std::showpos 是否互斥?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8424260/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com