如何打印uint64_t?失败:“格式中的虚假结尾'%'”


133

我写了一个非常简单的printf uint64_t测试代码:

#include <inttypes.h>
#include <stdio.h>

int main()
{
  uint64_t ui64 = 90;
  printf("test uint64_t : %" PRIu64 "\n", ui64);
  return 0;
}

我使用ubuntu 11.10(64位)和gcc版本4.6.1对其进行编译,但失败了:

main.cpp: In function int main()’:
main.cpp:9:30: error: expected ‘)’ before PRIu64
main.cpp:9:47: warning: spurious trailing ‘%’ in format [-Wformat]

1
看来您正在将C代码编译为C ++,这是您的错误。如果将文件重命名为main.cgcc并使用gcc进行编译,则一切都可以正常工作。
詹斯·古斯特


使用gcc或clang时,最好指定-std=c11您正在使用的标准或版本。抓住了这个和其他错误。我也-Wall -Wextra -Wpedantic -Wconversion至少建议。
戴维斯洛

Answers:


164

ISO C99标准规定只有在明确要求时才必须定义这些宏。

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work

@Dan,如果解决了问题,请不要忘记将答案标记为已接受(单击左侧的对勾图像)。
zneak 2011年

9
嗯,仅包含标题就足够了。__STDC_FORMAT_MACROS仅包含在C ++中才需要该宏。
Jens Gustedt

15
@Jens:的确;__STDC_FORMAT_MACROS仅在C99的脚注中出现,表明C ++仅在存在请求的情况下定义这些宏。但是,C ++委员会选择忽略该建议:例如,在n3242草案27.9.2 / 3中:注意:<cinttypes>定义的宏是无条件提供的。特别是,在C标准脚注182中提到的符号__STDC_FORMAT_MACROS在C ++中不起作用。 因此,当编译器赶上时,我们将不需要__STDC_FORMAT_MACROSC或C ++。
约翰·马歇尔

3
@John Marshall g ++ 4.7.3似乎需要该宏,即使包含<inttypes.h>也是如此。
crockeea

4
@Eric:显然g ++ 4.7.3尚未赶上!实际上,您可能将其与早于此错误修复的glibc版本一起使用。如该glibc报告中所述,您的g ++ 4.7.3的libstdc ++具有解决此问题的代码。如果您使用-std=c++0x#include <cinttypes>而不是<inttypes.h>进行编译,那么我相信它会在不提供的情况下提供格式宏__STDC_FORMAT_MACROS
约翰·马歇尔

4

在Centos 5.xi下编译memcached时遇到了同样的问题。

解决方案是至少将gcc和g ++升级到版本4.4。

编译之前,请确保将CC / CXX设置(导出)为正确的二进制文件。


1

由于已包含C ++标记,因此可以使用{fmt}库并完全避免PRIu64宏和其他printf问题:

#include <fmt/core.h>

int main() {
  uint64_t ui64 = 90;
  fmt::print("test uint64_t : {}\n", ui64);
}

提议基于该库的格式化工具用于C ++ 20:P0645中的标准化

免责声明:我是{fmt}的作者。


凉!还会有类似的东西sscanf吗?
ceztko

很有可能。我们正在研究更换的可能性scanf
vitaut

大!我也想知道是否有朝着独立于语言环境和/或语言环境可选版本的进展std::to_string()。cppreference页面仍然仅链接到std::to_chars(),这并不是人们真正需要的。我想知道fmt和/或c ++ 20是否处理过它。
ceztko

std::to_string可能会保持原样,但std::format允许您控制是否使用语言环境(默认情况下它不使用语言环境)。
vitaut
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.