Domanda

Sto cercando di stampare tipi come off_t e size_t. Qual è il segnaposto corretta per printf() che è portatile

O c'è un modo completamente diverso per stampare le variabili?

È stato utile?

Soluzione

È possibile utilizzare z per size_t e t per ptrdiff_t come in

printf("%zu %td", size, ptrdiff);

Ma la mia man dice qualche vecchia libreria utilizzato un carattere diverso rispetto z e scoraggia l'uso di esso. Tuttavia, è standardizzato (dallo standard C99). Per quei intmax_t e int8_t di stdint.h e così via, ci sono le macro è possibile utilizzare, come un'altra risposta ha detto:

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

Sono elencati nel suo manuale inttypes.h.

Personalmente, vorrei solo lanciare i valori unsigned long o long come un'altra risposta raccomanda. Se si utilizza C99, allora si può (e si deve, naturalmente) il cast unsigned long long o long long e utilizzare i formati %llu o %lld rispettivamente.

Altri suggerimenti

Per stampare off_t:

printf("%jd\n", (intmax_t)x);

Per stampare size_t:

printf("%zu\n", x);

Per stampare ssize_t:

printf("%zd\n", x);

Vedere 7.19.6.1/7 nello standard C99, oppure il più conveniente documentazione POSIX dei codici di formattazione:

http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

Se l'implementazione non supporta i codici di formattazione (ad esempio perché si è in C89), allora avete un po 'un problema dal momento che per quanto ne so non ci sono tipi interi in C89 che hanno codici di formattazione e sono garantiti per essere grande come questi tipi. Quindi è necessario fare qualcosa di implementazione specifici.

Per esempio se il compilatore ha long long e la vostra libreria standard supporta %lld, si può tranquillamente aspettare che servirà al posto di intmax_t. Ma se così non fosse, si dovrà ricadere long, che fallire su alcuni altre implementazioni perché è troppo piccolo.

Per Microsoft, la risposta è diversa. VS2013 è in gran parte C99 compatibile, ma "[l] a HH, J, Z, e t prefissi di lunghezza non sono supportati." per size_t "Cioè, __int32 unsigned su piattaforme a 32 bit, __int64 non firmato su piattaforme a 64 bit" l'uso del prefisso I (capitale occhio) con indicatore di tipo o, u, x, o X. Vedi Formato specifica VS2013

Per quanto riguarda off_t, si è definito il più a lungo in VC \ include sys \ types.h \.

Quale versione di C stai usando?

Nel C90, la pratica standard è di lanciare a firmato o unsigned long, a seconda dei casi, e la stampa di conseguenza. Ho visto% z per size_t, ma Harbison e Steele Non c'è di che sotto printf (), e in ogni caso non si farebbe aiutare con ptrdiff_t o qualsiasi altra cosa.

In C99, i vari tipi _t vengono con i loro macro printf, in modo da qualcosa come "Size is " FOO " bytes." non so i dettagli, ma questo fa parte di un gran formato numerico include file.

Ti consigliamo di utilizzare le macro di formattazione da inttypes.h.

Vedere questa domanda: Croce stringa di formato piattaforma per le variabili di tipo size_t?

Guardando man 3 printf su Linux, OS X, e OpenBSD tutto il supporto spettacolo per %z per size_t e %t per ptrdiff_t (per C99), ma nessuno di quelli menzione off_t. Suggerimenti in the wild di solito offrono la conversione %u per off_t, che è "abbastanza corretto", per quanto posso dire (sia unsigned int e off_t variano in modo identico tra i sistemi a 64-bit e 32-bit).

Ho visto questo post almeno due volte, perché la risposta accettata è difficile per ricordare per me (io uso raramente z o j bandiere e sono sembra non piattaforma indipendente ).

Il serie mai dice chiaramente l'esatta lunghezza dei dati di size_t, quindi vi suggerisco di dovrebbe innanzitutto verificare la lunghezza su size_t la vostra piattaforma quindi selezionare uno di loro:

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

E io suggerisco di usare tipi stdint invece di tipi di dati grezzi per la consistenza.

Se ricordo bene, l'unico modo portatile per farlo, è quello di gettare il risultato di "long int unsigned" e utilizzare %lu.

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));

utilizzare "% zo" per off_t. (Ottale) o "zu%", per decimali.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top