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.