Quel est l'argument en faveur de printf qui formate un long?

Réponses:

634

Mettez une l(lettre L minuscule) directement avant le spécificateur.

unsigned long n;
long m;

printf("%lu %ld", n, m);
postfuturiste
la source
14
printf("%ld", ULONG_MAX)renvoie la valeur sous la forme -1. Doit être printf("%lu", ULONG_MAX)non signé aussi longtemps que décrit par @Blorgbeard ci-dessous.
jammus
2
En fait, vous devriez le changer %ldpour être plus harmonique avec la question OP.
Dr Beco
Yep Dr Beco; plus loin, %ldéclenche justewarning: unknown conversion type character 0x20 in format [-Wformat]
Patrizio Bertoni
190

Je pense que vous voulez dire:

unsigned long n;
printf("%lu", n);   // unsigned long

ou

long n;
printf("%ld", n);   // signed long
Blorgbeard est sorti
la source
73

Sur la plupart des plateformes, longet intsont de la même taille (32 bits). Pourtant, il a son propre spécificateur de format:

long n;
unsigned long un;
printf("%ld", n); // signed
printf("%lu", un); // unsigned

Pour 64 bits, vous voudriez long long:

long long n;
unsigned long long un;
printf("%lld", n); // signed
printf("%llu", un); // unsigned

Oh, et bien sûr, c'est différent sous Windows:

printf("%l64d", n); // signed
printf("%l64u", un); // unsigned

Souvent, lorsque j'imprime des valeurs 64 bits, je trouve utile de les imprimer en hexadécimal (généralement avec des nombres aussi gros, ce sont des pointeurs ou des champs de bits).

unsigned long long n;
printf("0x%016llX", n); // "0x" followed by "0-padded", "16 char wide", "long long", "HEX with 0-9A-F"

imprimera:

0x00000000DEADBEEF

Au fait, "long" ne veut plus dire grand-chose (sur le x64 traditionnel). "int" est la taille int par défaut de la plate-forme, généralement 32 bits. "long" est généralement de la même taille. Cependant, ils ont une sémantique de portabilité différente sur les anciennes plates-formes (et les plates-formes intégrées modernes!). "long long" est un nombre 64 bits et généralement ce que les gens ont l'intention d'utiliser à moins qu'ils ne sachent vraiment ce qu'ils faisaient en modifiant un morceau de code portable x-platform. Même alors, ils auraient probablement utilisé une macro à la place pour capturer la signification sémantique du type (par exemple uint64_t).

char c;       // 8 bits
short s;      // 16 bits
int i;        // 32 bits (on modern platforms)
long l;       // 32 bits
long long ll; // 64 bits 

À l'époque, "int" était de 16 bits. On pourrait penser que ce serait maintenant 64 bits, mais non, cela aurait causé des problèmes de portabilité insensés. Bien sûr, même cela est une simplification de la vérité obscure et riche en histoire. Voir wiki: Entier

Dave Dopson
la source
@MM J'ai clarifié ma réponse pour éviter toute confusion.
Dave Dopson
4
Juste pour clarifier: il y a plus d'architectures que x86 et x64, et sur ces architectures, char, short, int, long et long long ont des significations différentes. Par exemple, un mcu 32 bits avec un alignement de mémoire 16 bits pourrait utiliser: char = short = int = 16 bit; long = 32 bits; long long = 64 bits
AndresR
1
@AndresR - absolument, et c'est très important pour les gens qui font de la programmation embarquée (j'ai construit une fois un module noyau pour un détecteur de fumée). Dommage ces pauvres âmes quand elles essaient d'utiliser du code qui n'a pas été écrit pour la portabilité.
Dave Dopson
Je ne suis pas sûr que "la plupart des plates-formes aient une longtaille 32", c'est toujours vrai. Par exemple, je suis sur Oracle Linux x86_64 / AMD64, et nvccun longest de 8 octets.
ragerdl
"Oh, et bien sûr, c'est différent sous Windows". Existe-t-il une solution multiplateforme?
Aaron Franke
17

Cela dépend, si vous faites référence à un long non signé, le caractère de formatage est "%lu". Si vous faites référence à une signature longue, le caractère de formatage est "%ld".

krato
la source
12

Dans le cas où vous cherchez à imprimer unsigned long longcomme moi, utilisez:

unsigned long long n;
printf("%llu", n);

Pour toutes les autres combinaisons, je pense que vous utilisez le tableau du manuel printf , en prenant la ligne, puis l'étiquette de colonne pour le type que vous essayez d'imprimer (comme je le fais printf("%llu", n)ci-dessus).

Dolan Antenucci
la source
0

Je pense que pour répondre définitivement à cette question, il faudrait connaître le nom et la version du compilateur que vous utilisez et la plate-forme (type de processeur, système d'exploitation, etc.) pour laquelle il compile.

Andrew O'Reilly
la source
Votre réponse doit être un commentaire et non une réponse en soi.
Jaime Hablutzel