【问题标题】:C function printf() limited in length?C 函数 printf() 的长度有限制吗?
【发布时间】:2013-03-05 12:19:32
【问题描述】:

调用 sprintf 函数格式化字符串时,打印了一些意想不到的东西

printf("%d;%s;%s;%d;%d;\n", ptr->programmaType, ptr->titel, ptr->zender, ptr->start, ptr->einde);

打印“0;星际之门;科幻;0;0;”而

printf("%d;", ptr->einde);

打印“42”,这是 ptr->einde 的值。我也试过了

printf("%d;%s;%s;%d;%d;", 0, "Stargate", "scifi", 0, 42);

打印正确,所以我猜测问题与变量有关。我尝试的最后一件事是

int bug = ptr->einde;
printf("%d;%s;%s;%d;%d;\n", ptr->programmaType, ptr->titel, ptr->zender, ptr->start, bug);

也无法正确打印...我不知道到底发生了什么。

注意:ptr->start 和 ptr->einde 被定义为 als time_t 类型,但看到 printf 使用单个参数我怀疑这是一个问题。

【问题讨论】:

  • 与您的问题不严格相关,但请不要用荷兰语编写代码。这是一个坏习惯。
  • 您能否为代码显示更多上下文?例如,您如何获得ptr?您是否将其作为指向函数中局部变量的指针返回?
  • 你在 64 位平台上吗?
  • "%d" 用于int;可能ptr->einde 是完全错误的其他东西:使用正确的说明符。
  • UB(未定义行为)的机制很奇怪:)

标签: c


【解决方案1】:

你说ptr->startptr->eindetime_t类型。这种类型不是完全可移植的,可以是任何"integer or real-floating type",因此当您尝试将它们打印为int 类型时,它们可能没有在您的系统上得到正确处理。

尝试将其转换为已知的内容,然后打印:

printf("%d;%s;%s;%ld;%ld;\n", ptr->programmaType, ptr->titel, 
    ptr->zender, (long)ptr->start, (long)ptr->einde);

【讨论】:

  • 这行得通!我仍然对为什么 printf("%d", ptr->einde) 确实打印“42”感到困惑,但至少我现在有一些工作了。
  • 查看pmg的cmets。是UB。 UB总是令人费解。 ;)
  • 这可能会发生:如果 ptr->start 是 64 位值,如果 int 是 32 位,那么最后两个 %d 说明符将打印高 32 位和低 32 位ptr->start 的位。
【解决方案2】:

我猜你对ptr->einde 的定义不是类型为int

您在 printf 说明符中使用了 "%d",它需要 int 值。
为正确的类型和 printf 行为使用正确的说明符。

【讨论】:

  • 我将一个 int 初始化为 53,并用这个整数替换了 time_t。它仍然在长 printf 中将此 int 打印为“0”,而如果我调用 printf("%d", int) 它会正确打印
  • @JelcoAdamczyk – 那是因为在你的长调用中有 2 个 time_ts,如果你将 ptr->startptr->einde 都替换为 int,你不会看到它的行为奇怪跨度>
  • 是的,对说明符和值使用错误的匹配会调用未定义的行为。您不希望在您的程序中使用 UB。始终正确匹配说明符和值(如果需要,使用强制转换)。
【解决方案3】:

不,printf 的长度不受限制,除非在嵌入式实现中它必须能够打印至少 4095 个字符。

time_t 可能是一个 64 位整数值。解决方案是将变量转换为 (uint64_t) 并使用 PRIu64 格式说明符。

printf("%d;%s;%s;%"PRIu64";%"PRIu64";\n", 
           ptr->programmaType, 
           ptr->titel, ptr->zender, 
           (uint64_t)ptr->start, 
           (uint64_t)ptr->einde);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 2011-01-17
    • 2010-12-02
    • 2012-01-10
    • 2012-07-25
    • 1970-01-01
    相关资源
    最近更新 更多