【问题标题】:Type of printf width specifierprintf 宽度说明符的类型
【发布时间】:2016-03-25 10:39:56
【问题描述】:

width 在下面的调用中应该是什么类型?

snprintf(buf, buflen, "%.*s", width, astring);

如何指定 width 以在 32 位和 64 位平台上正常工作?

在 64 位平台上宽度是否限制为 2**32

【问题讨论】:

  • width 必须是 int see this
  • 2**32(实际上是2**31-1)字符不够宽吗?
  • 如果INT_MAX不够用,当然不用snprintf也能达到同样的效果。

标签: c printf


【解决方案1】:

如何指定width 以在 32 位和 64 位平台上正常工作?

确保widthint 类型。

在这种情况下,代码使用 precision 字段 "%.*s",它也是 int


在 64 位平台上宽度是否限制为 2**32?

超过 4095 的任何内容都可能遇到问题:

  1. 问题在于int 的范围,而不是平台位宽。

  2. 单次转化宽度可能受限:

环境限制 任何一次转换可以产生的字符数至少应为 4095。 C11 §7.21.6.1 15

  1. int snprintf() 的返回值是打印的字符数。尝试打印超过INT_MAXtotal 个字符的调用可能会失败。

4。详细信息:snprintf(buf, buflen, "%.*s", width, astring); 中使用的width 是要打印的最少 个字符,并根据需要使用空格填充。

【讨论】:

  • 我想知道您的评论 4.:我从 GCC 得到的信息:%*s -- 从不截断,向右填充; %.*s -- 截断,从不填充; % *s -- 编译时警告。
  • @qama face-palm:我(错误地)说明了有关宽度字段而不是帖子使用的精度字段的内容。
【解决方案2】:

如果您将其声明为int,则该宽度将适用于所有平台。 int 的实际大小取决于平台。

要为星号传递的类型在 C99 标准第 7.19.6.1.5 节中指定:

字段宽度或精度或两者都可以用星号表示。在这种情况下,int 参数提供字段宽度或精度。指定字段宽度或精度或两者的参数应(按该顺序)出现在要转换的参数(如果有)之前。负字段宽度参数被视为 - 标志,后跟正字段宽度。

只要您声明int width,您的代码就会在所有符合标准的平台上正常运行。

在 64 位平台上宽度是否限制为 232

int 的大小是特定于实现的。在 64 位平台上可能是 32 位,在这种情况下宽度将被限制为 231-1,因为负数的解释不同。

【讨论】:

  • 这是否意味着LLP64LP64 数据模型对宽度长度施加了限制,这意味着无法将64 位宽度参数提供给*printf
  • @qarma 是的,LLP64 和 LP64 use 32-bit integers。只有 ILP64 使用 64 位整数。
  • 而且一旦你想输出这么多字符,你肯定不会使用 printf()。
  • 谢谢,@joop 我想确定我可以使用指针算术,比如width = ptr1 - ptr2,后者是结果,例如strchr().
  • 不要那样做。或者使用强制转换 (int)( ptr1-ptr2) 强制 printf 的参数是一个实际的 int。 (因为他们无法推断它们,可变参数函数依赖于传递的正确类型)
猜你喜欢
  • 2020-02-05
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
  • 2020-05-23
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多