Sto provando a stampare tipi come off_t
e size_t
. Qual è il segnaposto corretto per printf()
che è portatile?Come devo stampare tipi come off_t e size_t?
Oppure c'è un modo completamente diverso di stampare quelle variabili?
Sto provando a stampare tipi come off_t
e size_t
. Qual è il segnaposto corretto per printf()
che è portatile?Come devo stampare tipi come off_t e size_t?
Oppure c'è un modo completamente diverso di stampare quelle variabili?
È possibile utilizzare z
per size_t e t
per ptrdiff_t come in
printf("%zu %zd", size, ptrdiff);
Ma la mia man dice qualche vecchia libreria utilizzato un carattere diverso rispetto z
e scoraggia l'uso di esso. Tuttavia, è standardizzato (secondo lo standard C99). Per coloro 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);
Essi sono elencati nel suo manuale inttypes.h
.
Personalmente, vorrei semplicemente trasmettere i valori a unsigned long
o long
come suggerito da un'altra risposta. Se si utilizza C99, è possibile (e dovrebbe, ovviamente) trasmettere a unsigned long long
o long long
e utilizzare rispettivamente i formati %llu
o %lld
.
Poiché PRId32 non include lo specificatore di formato%, non dovrebbe essere 'printf (" valore:% "PRId32, some_int32_t);' –
off_t è in realtà un long firmato lungo il mio sistema. –
sì per i valori firmati che dovrai convertire a lungo o lungo. quest'ultimo tipo non esiste nel C++ corrente, ma la prossima versione lo include. specialmente se lavori con posix e include alcuni tipi come off_t che hanno dimensioni grandi, devi stare attento. –
Quale versione di C stai utilizzando?
In C90, lo standard è quello di trasmettere a firma o non firmata a lungo, a seconda dei casi, e stampare di conseguenza. Ho visto% z per size_t, ma Harbison e Steele non lo menzionano sotto printf(), e in ogni caso ciò non ti può aiutare con ptrdiff_t o qualsiasi altra cosa.
In C99, i vari tipi _t sono dotati di macro printf, quindi qualcosa come "Size is " FOO " bytes."
non conosco i dettagli, ma fa parte di un file numerico di formato abbastanza grande.
Quale edizione di H & S - la quinta quasi certamente la menziona ... –
Quarta edizione - dovrei aggiornare? –
Come ricordo, l'unico modo portatile per farlo è quello di trasmettere il risultato a "unsigned long int" e utilizzare %lu
.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
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
. I suggerimenti in natura solitamente offrono la conversione %u
per off_t
, che è "abbastanza corretta" per quanto posso dire (sia unsigned int
che off_t
variano in modo identico tra i sistemi a 64 e 32 bit).
Il mio sistema (OS X) ha 'unsigned int' a 32 bit e' off_t' a 64 bit. Quindi il cast causerebbe la perdita di dati. –
Dovrai utilizzare le macro di formattazione di inttypes.h.
Vai a questa domanda: Cross platform format string for variables of type size_t?
Non risponde come formattare off_t. – stepancheg
Supponendo che off_t sia un int firmato, con dimensioni del puntatore (non so quale sia la definizione precisa) come ptrdiff_t, allora useresti PRIdPTR o PRIiPTR. –
Il tipo 'off_t' è più grande di un puntatore su qualsiasi sistema a 32 bit che supporta file di grandi dimensioni (che attualmente è la maggior parte dei sistemi a 32 bit). –
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ù comoda 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 grandi come questi tipi. Quindi devi fare qualcosa di specifico per l'implementazione.
Ad esempio se il compilatore dispone di long long
e la libreria standard supporta %lld
, è possibile attendersi che funzioni al posto di intmax_t
. Ma se così non fosse, dovrai ricorrere a long
, che fallirebbe in alcune altre implementazioni perché è troppo piccolo.
Questa è di gran lunga la risposta migliore, mi sarei dimenticato di usare% zu per size_t senza segno. E trasmettere a intmax_t è un'ottima soluzione per qualsiasi cosa off_t sia su qualsiasi piattaforma. –
POSIX non garantisce che 'ssize_t' abbia le stesse dimensioni di' size_t', quindi il codice veramente portatile dovrebbe convertirlo in 'intmax_t' e stampare con'% jd' come 'off_t'. – nwellnhof
Si prega di utilizzare% lu. Off_t non è firmato a lungo.
Avete qualche specifica * che garantisca * questo? Solo perché qualcosa sembra essere vero per un determinato OS del compilatore/target non significa che sia sempre vero. – CodesInChaos
Questo, e sembra che le definizioni varino, ma intuitivamente mi aspetto che qualsiasi implementazione sana di un offset sia un tipo firmato, per ovvi motivi. –
Per Microsoft, la risposta è diversa. VS2013 è ampiamente compatibile con C99 ma "[i] i prefissi hh, j, z e t non sono supportati." Per size_t "cioè __int32 non firmato su piattaforme a 32 bit, __int64 non firmato su piattaforme a 64 bit" l'uso del prefisso I (occhio del capitale) con indicatore di tipo o, u, x, o X. See VS2013 Size specification
Per quanto riguarda off_t , è definito come lungo in VC \ include \ sys \ types.h.
Nota se 'off_t' è sempre' long' che lo renderebbe a 32 bit (anche Windows a 64 bit usa 32 bit per 'long'). – sourcejedi
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 non sembra platform independant).
Il standard mai dice chiaramente l'esatta lunghezza dei dati di size_t
, quindi vi suggerisco di dovrebbe innanzitutto verificare la lunghezza size_t
sulla 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 stdint
tipi invece di tipi di dati non elaborati per coerenza.
Per C99 e C11, lo standard afferma esplicitamente che '% zu' può essere usato per stampare i valori di' size_t'. Uno dovrebbe * sicuramente non * ricorrere all'utilizzo di un identificatore di formato 'uint32_t' /' uint64_t' per stampare un 'size_t', in quanto non vi è alcuna garanzia che quei tipi siano compatibili. – Sebivor
@devin: Credo di aver trovato quel tipo durante l'utilizzo di 'fopen',' fseek', ecc. Su Mac OS X. 'off_t' viene utilizzato per l'offset. –