【问题标题】:Why would an int be formatted as %#X in a printf function?为什么 int 在 printf 函数中会被格式化为 %#X?
【发布时间】:2020-11-10 20:45:53
【问题描述】:

我正在调试一些代码(不是我自己编写的),并且在 printf 函数中使用 %#X 打印了一个 int index。据我了解%#X 是一个大写的无符号 十六进制整数。

这样可以吗/有什么办法可以解决吗?

【问题讨论】:

    标签: c printf format-specifiers


    【解决方案1】:

    据我了解,%#X 是一个大写的无符号十六进制整数。

    这是正确的,根据 C 标准,对应于 %#X 的参数应该是 unsigned int,并且传递 int 的行为在技术上并未由 C 标准定义,根据 C 2018 7.21。 6.1 8(表示X 代表unsigned int)和9(“如果任何参数不是相应转换规范的正确类型,则行为未定义。”)

    实际上,几乎没有 C 实现(如果有的话)会抱怨这一点,或者除了将int 的位重新解释为unsigned int 之外的行为。

    这样可以吗/有什么办法可以解决吗?

    要使代码正确无误,请将参数强制转换为 unsigned int

    【讨论】:

    • 代码正在测试以验证index 是否满足最小长度要求,如果不满足,则打印错误消息和索引,格式为%#X。所以我假设在索引为负值的情况下(可能很少见)索引被定义为int。但这意味着将有符号值作为%#X 的输入是未定义的,正如您所说...对不起,可能是我在问题描述中没有提供足够信息的错,有人告诉我我正在使用的代码是敏感的所以我不想发布太多信息。
    【解决方案2】:

    # 转换说明符表示应使用替代转换。

    来自cppreference

    在替代实现中,0x0X 是结果的前缀,如果 转换后的值非零。

    所以,这似乎是作者故意的。

    如果您询问的是 unsigned 部分,%Xalways 未签名的。如果您有一个带符号的值,并且您希望您的十六进制值以负号为前缀,则您必须自己滚动。

    否则,将有符号值作为输入是很好的——它只会被重新解释为无符号。除非这是您在程序中发现的错误! ;)

    【讨论】:

    • 关于“将有符号值作为输入很好”:C 2018 7.21.6.1 9 表示行为未定义。
    【解决方案3】:

    # 结合X 格式将在以大写十六进制格式打印您的index 值之前打印0X
    看起来完全没问题,如果没有进一步的解释,我们无法为您提供“解决此问题的方法”。

    【讨论】:

    • Re “看起来完全没问题”:C 2018 7.21.6.1 9 表示行为未定义。关于“我们无法为您提供“解决此问题的方法”:投射到 unsigned int 是一种解决方法。
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 2018-11-23
    • 2019-10-18
    • 2012-08-04
    • 2021-07-05
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多