Saya mencoba untuk mencetak jenis suka off_t
dan size_t
. Apa placeholder yang benar untuk printf()
itu portabel ?
Atau adakah cara yang sama sekali berbeda untuk mencetak variabel-variabel itu?
c
portability
format-specifiers
Georg Schölly
sumber
sumber
fopen
,fseek
, dll di Mac OS X.off_t
digunakan untuk offset.Jawaban:
Anda dapat menggunakan
z
untuk size_t dant
untuk ptrdiff_t seperti diTetapi halaman buku saya mengatakan beberapa perpustakaan yang lebih tua menggunakan karakter yang berbeda dari
z
dan tidak mendukungnya. Namun demikian, itu standar (dengan standar C99). Bagi merekaintmax_t
danint8_t
daristdint.h
dan seterusnya, ada makro yang dapat Anda gunakan, seperti jawaban lain yang dikatakan:Mereka terdaftar di halaman manual
inttypes.h
.Secara pribadi, saya hanya akan memberikan nilai
unsigned long
ataulong
menyukai jawaban yang direkomendasikan. Jika Anda menggunakan C99, maka Anda dapat (dan harus, tentu saja) cor untukunsigned long long
ataulong long
dan menggunakan%llu
atau%lld
format masing-masing.sumber
%zd
dengansize_t
adalah perilaku undefined karena signedness mismatch (C99 7.19.6.1 # 9). Pasti begitu%zu
.%zd
dengansize_t
perilaku yang tidak terdefinisi dari paragraf itu atau dari yang lain. Pada kenyataannya, definisi%z
dalam # 7 secara eksplisit memungkinkan%d
dengansize_t
dan jenis bertanda tangan yang sesuai, dan §6.2.5 # 9 secara eksplisit memungkinkan penggunaan nilai-nilai dari jenis yang tidak ditandatangani di mana jenis yang ditandatangani diharapkan, asalkan nilainya adalah nilai nonnegatif yang valid dari tipe yang ditandatangani.Untuk mencetak
off_t
:Untuk mencetak
size_t
:Untuk mencetak
ssize_t
:Lihat 7.19.6.1/7 dalam standar C99, atau dokumentasi POSIX yang lebih mudah tentang kode pemformatan:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Jika implementasi Anda tidak mendukung kode pemformatan tersebut (misalnya karena Anda menggunakan C89), maka Anda memiliki sedikit masalah karena AFAIK tidak ada tipe integer di C89 yang memiliki kode pemformatan dan dijamin sebesar sebagai tipe ini. Jadi, Anda perlu melakukan sesuatu yang spesifik implementasi.
Misalnya jika kompiler Anda memiliki
long long
dan pustaka standar Anda mendukung%lld
, Anda dapat dengan yakin mengharapkan yang akan menggantikannyaintmax_t
. Tetapi jika tidak, Anda harus kembali kelong
, yang akan gagal pada beberapa implementasi lain karena terlalu kecil.sumber
ssize_t
memiliki ukuran yang samasize_t
, jadi kode yang benar-benar portabel harus mengubahnya menjadiintmax_t
dan mencetak%jd
sepertioff_t
.Untuk Microsoft, jawabannya berbeda. VS2013 sebagian besar memenuhi persyaratan C99 tetapi "[t] heh, j, z, dan t panjang prefix tidak didukung." Untuk size_t "yaitu, unsigned __int32 pada platform 32-bit, unsigned __int64 pada platform 64-bit" gunakan awalan I (modal mata) dengan specifier tipe o, u, x, atau X. Lihat spesifikasi ukuran VS2013
Sedangkan untuk off_t, ini didefinisikan sebagai panjang dalam VC \ include \ sys \ types.h.
sumber
off_t
selalulong
itu akan membuatnya 32-bit (bahkan 64-bit Windows menggunakan 32-bit untuklong
).Versi C mana yang Anda gunakan?
Di C90, praktik standar adalah menggunakan untuk ditandatangani atau tidak ditandatangani lama, yang sesuai, dan cetak sesuai. Saya telah melihat% z untuk size_t, tetapi Harbison dan Steele tidak menyebutkannya di bawah printf (), dan dalam hal apa pun itu tidak akan membantu Anda dengan ptrdiff_t atau apa pun.
Di C99, berbagai jenis _t datang dengan makro printf mereka sendiri, jadi sesuatu seperti
"Size is " FOO " bytes."
saya tidak tahu detailnya, tapi itu bagian dari format numerik yang cukup besar termasuk file.sumber
Anda ingin menggunakan makro pemformatan dari inttypes.h.
Lihat pertanyaan ini: String format platform silang untuk variabel tipe size_t?
sumber
off_t
jenis lebih besar dari pointer pada sistem 32-bit yang mendukung file besar (yang paling 32-bit sistem hari ini).Melihat di
man 3 printf
Linux, OS X, dan OpenBSD semuanya menunjukkan dukungan%z
untuksize_t
dan%t
untukptrdiff_t
(untuk C99), tetapi tidak satupun yang menyebutkanoff_t
. Saran di alam liar biasanya menawarkan%u
konversioff_t
, yang "cukup benar" sejauh yang saya tahu (keduanyaunsigned int
danoff_t
bervariasi secara identik antara sistem 64-bit dan 32-bit).sumber
unsigned int
dan 64-bitoff_t
. Jadi para pemain akan menyebabkan data menjadi hilang.Saya melihat posting ini setidaknya dua kali, karena jawaban yang diterima sulit untuk diingat bagi saya (saya jarang menggunakan
z
atauj
menandai dan mereka tampaknya bukan platform independen ).The standar tidak pernah mengatakan secara jelas panjang data yang tepat dari
size_t
, jadi saya sarankan pertama Anda harus memeriksa panjangsize_t
pada platform Anda kemudian pilih salah satu dari mereka:Dan saya sarankan menggunakan
stdint
tipe daripada tipe data mentah untuk konsistensi.sumber
%zu
dapat digunakan untuk mencetaksize_t
nilai. Satu harus pasti tidak resor untuk menggunakanuint32_t
/uint64_t
format yang specifier untuk mencetaksize_t
, karena tidak ada jaminan bahwa jenis-jenis yang kompatibel.Seingat saya, satu-satunya cara portabel untuk melakukannya, adalah membuang hasilnya ke "unsigned long int" dan gunakan
%lu
.sumber
long long
tidak ada dalam standar C ++, dan dengan demikian bersifat non-portabel.gunakan "% zo" untuk off_t. (oktal) atau "% zu" untuk desimal.
sumber