Come stampare uint64_t? Non riesce con: "spuria trailing '%' nel formato"


133

Ho scritto un codice di prova molto semplice di printf uint64_t:

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

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

Uso Ubuntu 11.10 (64 bit) e gcc versione 4.6.1 per compilarlo, ma fallito:

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
Sembra che tu stia compilando il codice C come C ++, questo è il tuo errore. Se rinomini il tuo file main.ce lo compili con gcc, tutto dovrebbe funzionare bene.
Jens Gustedt,


Con gcc o clang, è una buona idea specificare -std=c11o la versione dello standard che si sta utilizzando. Questo cattura questo e altri errori. Raccomando anche -Wall -Wextra -Wpedantic -Wconversionalmeno.
Davislor,

Risposte:


164

Lo standard ISO C99 specifica che queste macro devono essere definite solo se esplicitamente richiesto.

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work

@Dan, non dimenticare di contrassegnare la risposta come accettata (fare clic sull'immagine del segno di spunta a sinistra) se ha risolto il problema.
zneak,

9
Hm, basterà includere solo l'intestazione. La __STDC_FORMAT_MACROSmacro è richiesta solo per l'inclusione in C ++.
Jens Gustedt,

15
@Jens: davvero; __STDC_FORMAT_MACROSappare solo in una nota a piè di pagina in C99, suggerendo che C ++ definisce queste macro solo in presenza della richiesta. Tuttavia, il comitato C ++ ha scelto di ignorare il suggerimento: ad es. Nella bozza n3242, 27.9.2 / 3: Nota: le macro definite da <cinttypes> sono fornite incondizionatamente. In particolare, il simbolo __STDC_FORMAT_MACROS, menzionato nella nota 182 della norma C, non ha alcun ruolo in C ++. Quindi, quando i compilatori raggiungono, non avremo bisogno __STDC_FORMAT_MACROSin C o C ++.
John Marshall,

3
@John Marshall g ++ 4.7.3 sembra richiedere la macro, anche quando è incluso <inttypes.h>.
crockeea,

4
@Eric: Apparentemente g ++ 4.7.3 non aveva raggiunto! In effetti, probabilmente lo stai usando con una versione di glibc che precede questa correzione di bug . Come discusso in quel rapporto glibc, libstdc ++ di g ++ 4.7.3 ha del codice per aggirare questo problema. Se si compila con -std=c++0xe forse #include <cinttypes> anziché <inttypes.h>, credo che fornirebbe le macro di formato senza che tu lo fornisca __STDC_FORMAT_MACROS.
John Marshall,

4

Durante la compilazione di memcached in Centos 5.xi si è verificato lo stesso problema.

La soluzione è di aggiornare almeno gcc e g ++ alla versione 4.4.

Assicurati che il tuo CC / CXX sia impostato (esportato) sui binari di destra prima di compilare.


1

Dato che hai incluso il tag C ++, puoi utilizzare la libreria {fmt} ed evitare del tutto la PRIu64macro e altri printfproblemi:

#include <fmt/core.h>

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

La funzione di formattazione basata su questa libreria è proposta per la standardizzazione in C ++ 20: P0645 .

Disclaimer : sono l'autore di {fmt}.


Freddo! Sta arrivando anche qualcosa di simile a sscanf?
ceztko,

Molto probabilmente. Stiamo studiando la possibilità di sostituire scanf.
vitaut,

Grande! Inoltre mi chiedo se ci sono progressi verso una versione indipendente e / o selezionabile dalla locale di std::to_string(). La pagina cppreference rimanda ancora solo al link std::to_chars(), che non è proprio ciò di cui le persone hanno bisogno. Mi chiedo se fmte / o c ++ 20 se ne occupi o no ancora.
ceztko,

std::to_stringrimarrà probabilmente così com'è, ma std::formatti consente di controllare se utilizzare le impostazioni locali o meno (e per impostazione predefinita non utilizza le impostazioni locali).
vitaut,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.