Comment printf uint64_t? Échec avec: "faux"% "à la fin du format"


133

J'ai écrit un code de test très simple de printf uint64_t:

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

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

J'utilise ubuntu 11.10 (64 bits) et gcc version 4.6.1 pour le compiler, mais j'ai échoué:

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
Il semble que vous compilez du code C en C ++, c'est votre erreur. Si vous renommez votre fichier main.cet le compilez avec gcc, tout devrait fonctionner correctement.
Jens Gustedt


Avec gcc ou clang, c'est une bonne idée de spécifier -std=c11ou la version de la norme que vous utilisez. Cela rattrape cela et d'autres erreurs. Je recommande aussi -Wall -Wextra -Wpedantic -Wconversionau moins.
Davislor

Réponses:


164

La norme ISO C99 spécifie que ces macros ne doivent être définies que si elles sont explicitement demandées.

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work

@Dan, n'oubliez pas de marquer la réponse comme acceptée (cliquez sur l'image de la coche à gauche) si elle a résolu votre problème.
zneak

9
Hm, il suffit d'inclure l'en-tête. La __STDC_FORMAT_MACROSmacro n'est requise que pour l'inclusion dans C ++.
Jens Gustedt

15
@Jens: En effet; __STDC_FORMAT_MACROSapparaît uniquement dans une note de bas de page en C99, suggérant que C ++ ne définisse ces macros qu'en présence de la requête. Cependant, le comité C ++ a choisi d'ignorer la suggestion: par exemple dans le projet n3242, 27.9.2 / 3: Note: Les macros définies par <cinttypes> sont fournies sans condition. En particulier, le symbole __STDC_FORMAT_MACROS, mentionné dans la note de bas de page 182 du standard C, ne joue aucun rôle en C ++. Ainsi, lorsque les compilateurs rattraperont leur retard, nous n'aurons pas besoin __STDC_FORMAT_MACROSde C ou C ++.
John Marshall

3
@John Marshall g ++ 4.7.3 semble exiger la macro, même lorsque <inttypes.h> est inclus.
crockeea

4
@Eric: Apparemment, g ++ 4.7.3 n'avait pas rattrapé son retard! En fait, vous l'utilisez probablement avec une version glibc antérieure à cette correction de bogue . Comme indiqué dans ce rapport de la glibc, la libstdc ++ de votre g ++ 4.7.3 a du code pour contourner ce problème. Si vous compilez avec -std=c++0xet peut-être #include <cinttypes> plutôt que <inttypes.h>, je crois que cela fournirait les macros de format sans que vous fournissiez __STDC_FORMAT_MACROS.
John Marshall

4

Lors de la compilation de memcached sous Centos 5.xi a eu le même problème.

La solution consiste à mettre à niveau gcc et g ++ au moins vers la version 4.4.

Assurez-vous que votre CC / CXX est défini (exporté) sur les bons binaires avant la compilation.


1

Puisque vous avez inclus la balise C ++, vous pouvez utiliser la bibliothèque {fmt} et éviter complètement la PRIu64macro et d'autres printfproblèmes:

#include <fmt/core.h>

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

La fonction de formatage basée sur cette bibliothèque est proposée pour la normalisation en C ++ 20: P0645 .

Avertissement : je suis l'auteur de {fmt}.


Cool! Vient-il aussi quelque chose de similaire sscanf?
ceztko

Très probablement. Nous étudions la possibilité de remplacer scanf.
vitaut

Génial! Je me demande également s'il y a des progrès vers une version locale indépendante et / ou sélectionnable de std::to_string(). La page cppreference renvoie toujours uniquement vers std::to_chars(), ce qui n'est pas vraiment ce dont les gens ont besoin. Je me demande si fmtet / ou c ++ 20 s'en occupe ou pas encore.
ceztko

std::to_stringrestera probablement tel std::formatquel , mais vous permet de contrôler si vous souhaitez utiliser la locale ou non (et par défaut, elle n'utilise pas la locale).
vitaut
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.