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.cをgccに変更してコンパイルすると、すべて正常に動作するはずです。
Jens Gustedt、2011年


gccまたはclangのいずれかを使用する-std=c11場合、または使用している標準のバージョンを指定することをお勧めします。これは、このエラーやその他のエラーをキャッチします。-Wall -Wextra -Wpedantic -Wconversion少なくともお勧めします。
Davislor、

回答:


164

ISO C99標準では、これらのマクロは明示的に要求された場合にのみ定義する必要があると規定しています。

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work

@Dan、問題が解決した場合は、回答を承認済みとしてマークすることを忘れないでください(左側のチェックマーク画像をクリックしてください)。
zneak

9
うーん、ヘッダーを含めるだけで十分です。__STDC_FORMAT_MACROSマクロのみC ++に含めるために必要とされます。
Jens Gustedt、2011年

15
@イェンス:確かに; __STDC_FORMAT_MACROSC99の脚注にのみ表示され、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 2013年

4
@エリック:どうやらg ++ 4.7.3が追いついていなかったようです!実際、おそらくあなたはこのバグ修正より前のglibcバージョンでそれを使用しているでしょう。そのglibcレポートで説明されているように、g ++ 4.7.3のlibstdc ++には、この問題を回避するためのコードが含まれています。-std=c++0x<inttypes.h>ではなく#include <cinttypes> を使用してコンパイルした場合、を指定しなくてもフォーマットマクロが提供されると思います__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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.