Wie drucke ich uint64_t? Schlägt fehl mit: "falsches abschließendes '%' im Format"


133

Ich habe einen sehr einfachen Testcode von printf uint64_t geschrieben:

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

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

Ich verwende Ubuntu 11.10 (64 Bit) und gcc Version 4.6.1, um es zu kompilieren, aber es ist fehlgeschlagen:

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
Es scheint, dass Sie C-Code als C ++ kompilieren, das ist Ihr Fehler. Wenn Sie Ihre Datei umbenennen main.cund mit gcc kompilieren, sollte alles einwandfrei funktionieren.
— Jens Gustedt


Mit gcc oder clang ist es eine gute Idee, -std=c11die Version des von Ihnen verwendeten Standards anzugeben . Das fängt diesen und andere Fehler auf. Ich empfehle auch -Wall -Wextra -Wpedantic -Wconversionzumindest.
— Davislor

Antworten:


164

Der ISO C99-Standard legt fest, dass diese Makros nur definiert werden dürfen, wenn dies ausdrücklich angefordert wird.

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work

@Dan, vergessen Sie nicht, die Antwort als akzeptiert zu markieren (klicken Sie auf das Häkchen links), wenn das Problem dadurch behoben wurde.
— Zneak

9
Hm, nur den Header einzuschließen sollte ausreichen. Das __STDC_FORMAT_MACROSMakro wird nur für die Aufnahme in C ++ benötigt.
— Jens Gustedt

15
@Jens: In der Tat; __STDC_FORMAT_MACROSwird in C99 nur in einer Fußnote angezeigt, was darauf hindeutet, dass C ++ diese Makros nur bei Vorhandensein der Anforderung definiert. Das C ++ - Komitee hat sich jedoch entschieden, den Vorschlag zu ignorieren: z. B. im Entwurf von n3242, 27.9.2 / 3: Hinweis: Die durch <cinttypes> definierten Makros werden unbedingt bereitgestellt. Insbesondere das in Fußnote 182 des C-Standards erwähnte Symbol __STDC_FORMAT_MACROS spielt in C ++ keine Rolle. Wenn die Compiler aufholen, brauchen wir __STDC_FORMAT_MACROSweder C noch C ++.
— John Marshall

3
@ John Marshall g ++ 4.7.3 scheint das Makro zu erfordern, auch wenn <inttypes.h> enthalten ist.
— Crockeea

4
@ Eric: Anscheinend hatte g ++ 4.7.3 nicht aufgeholt! Wahrscheinlich verwenden Sie es sogar mit einer glibc-Version, die vor dieser Fehlerbehebung erstellt wurde . Wie in diesem glibc-Bericht erläutert, verfügt libstdc ++ in g ++ 4.7.3 über Code, um dieses Problem zu umgehen. Wenn Sie mit -std=c++0x<cinttypes> anstelle von <inttypes.h> kompilieren und möglicherweise #include verwenden, werden die Formatmakros meiner Meinung nach ohne Ihre Angabe bereitgestellt __STDC_FORMAT_MACROS.
— John Marshall

4

Beim Kompilieren von Memcached unter Centos 5.xi trat das gleiche Problem auf.

Die Lösung besteht darin, gcc und g ++ mindestens auf Version 4.4 zu aktualisieren.

Stellen Sie vor dem Kompilieren sicher, dass Ihr CC / CXX auf die richtigen Binärdateien eingestellt (exportiert) ist.


1

Da Sie das C ++ - Tag eingefügt haben, können Sie die {fmt} -Bibliothek verwenden und das PRIu64Makro und andere printfProbleme insgesamt vermeiden :

#include <fmt/core.h>

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

Die auf dieser Bibliothek basierende Formatierungsfunktion wird zur Standardisierung in C ++ 20: P0645 vorgeschlagen .

Haftungsausschluss : Ich bin der Autor von {fmt}.


Cool! Kommt es auch so ähnlich sscanf?
— Ceztko

Möglicherweise. Wir prüfen die Möglichkeit des Austauschs scanf.
— Vitaut

Toll! Ich frage mich auch, ob es Fortschritte in Richtung einer vom Gebietsschema unabhängigen und / oder vom Gebietsschema auswählbaren Version von gibt std::to_string(). Die cppreference-Seite verlinkt immer noch nur auf std::to_chars(), was die Leute nicht wirklich brauchen. Ich frage mich, ob fmtund / oder c ++ 20 damit umgehen oder noch nicht.
— Ceztko

std::to_stringwird wahrscheinlich unverändert bleiben, aber std::formatSie können steuern, ob das Gebietsschema verwendet werden soll oder nicht (und standardmäßig wird das Gebietsschema nicht verwendet).
— Vitaut
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.