Indipendente dalla piattaforma size_t Specificatori di formato in c?


86

Voglio stampare una variabile di tipo size_tin C ma sembra che size_tsia alias per diversi tipi di variabili su diverse architetture. Ad esempio, su una macchina (64 bit) il codice seguente non genera alcun avviso:

size_t size = 1;
printf("the size is %ld", size);

ma sull'altra mia macchina (32 bit) il codice sopra produce il seguente messaggio di avviso:

avviso: il formato "% ld" prevede il tipo "long int *", ma l'argomento 3 ha il tipo "size_t *"

Sospetto che ciò sia dovuto alla differenza nella dimensione del puntatore, in modo che sulla mia macchina a 64 bit size_tvenga applicato un alias a long int( "%ld"), mentre sulla mia macchina a 32 bit l' size_talias è di un altro tipo.

Esiste un identificatore di formato specifico per size_t?


Il tuo messaggio di avviso non corrisponde al codice. L'avviso menziona i puntatori, il tuo codice non ne ha. Hai rimosso da qualche &parte?
— Jens

Puntatori? No, non ricevo alcun avviso sui puntatori, infatti a seconda della macchina su cui eseguo quel codice a volte non ricevo alcun avviso. Prova il seguente codice di prova: #include <stdio.h> int main () {size_t size = 1; printf ("la dimensione è% ld", size); return 0; }
— Ethan Heilman


1
@EthanHeilman Si riferisce al fatto che i tuoi avvertimenti dicono warning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *'quando probabilmente dovrebbe essere detto warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t'. Forse stavi usando scanf()invece quando hai ricevuto questi avvisi?
— RastaJedi

Risposte:


123

Sì: usa il zmodificatore di lunghezza:

size_t size = sizeof(char);
printf("the size is %zu\n", size);  // decimal size_t ("u" for unsigned)
printf("the size is %zx\n", size);  // hex size_t

Gli altri modificatori di lunghezza disponibili sono hh(for char), h(for short), l(for long), ll(for long long), j(for intmax_t), t(for ptrdiff_t) e L(for long double). Vedere §7.19.6.1 (7) dello standard C99.


qual è la differenza tra zd e zu? Ho capito che zd è decimale, ma è firmato, in tal caso in che modo il segno zd ha effetto sulle cose.
— Ethan Heilman

1
È la differenza tra a size_te an ssize_t; quest'ultimo è usato raramente.
— Adam Rosenfield,

26
Bene, quindi in questo caso dovresti usare %zu, perché l'argomento non è firmato.
— caf

Le altre opzioni disponibili sono spiegate nella pagina di manuale di printf: linux.die.net/man/3/printf
— INS

9
@detly: No, il zmodificatore di lunghezza non fa parte di C89 / C90. Se stai mirando a un codice conforme a C89, il meglio che puoi fare è eseguire il cast unsigned longe utilizzare linvece il modificatore di lunghezza, ad esempio printf("the size is %lu\n", (unsigned long)size);; supportare sia C89 che sistemi con size_tdimensioni maggiori di longè più complicato e richiederebbe l'utilizzo di un numero di macro del preprocessore.
— Adam Rosenfield

45

Si C'è. È %zu(come specificato in ANSI C99).

size_t size = 1;
printf("the size is %zu", size);

Nota che size_tnon è firmato, quindi %ldè doppio sbagliato: modificatore di lunghezza errato e specificatore di conversione di formato errato. Nel caso ve lo chiediate, %zdè per ssize_t(che è firmato).


1

MSDN , afferma che Visual Studio supporta il prefisso "I" per il codice portabile su piattaforme a 32 e 64 bit.

size_t size = 10;
printf("size is %Iu", size);

6
è specifico per MS, che non è conforme agli standard, quindi non è indipendente dalla piattaforma
— phuclv

@phuclv Indeed. E se davvero dice - come suggerisce la risposta - "portatile" è anche peggio di quanto avessi mai saputo sulla SM. Non che mi sorprenderebbe ... Non sono il tipo da votare perché qualcuno ha fatto lo sforzo di provare a rispondere a qualcosa, ma questa risposta è semplicemente sbagliata. Ah, penso di aver capito l'idea qui in "portatile". Va detto che funziona sia per 32 bit che per 64 bit. Ma ovviamente lo sarebbe.
— Pryftan
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.