Saya mencoba untuk mencetak jenis suka off_tdan size_t. Apa placeholder yang benar untuk printf() itu portabel ?
Atau adakah cara yang sama sekali berbeda untuk mencetak variabel-variabel itu?
Saya mencoba untuk mencetak jenis suka off_tdan size_t. Apa placeholder yang benar untuk printf() itu portabel ?
Atau adakah cara yang sama sekali berbeda untuk mencetak variabel-variabel itu?
Jawaban:
Anda dapat menggunakan zuntuk size_t dan tuntuk ptrdiff_t seperti di
printf("%zu %td", size, ptrdiff);
Tetapi halaman buku saya mengatakan beberapa perpustakaan yang lebih tua menggunakan karakter yang berbeda dari zdan tidak mendukungnya. Namun demikian, itu standar (dengan standar C99). Bagi mereka intmax_tdan int8_tdari stdint.hdan seterusnya, ada makro yang dapat Anda gunakan, seperti jawaban lain yang dikatakan:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Mereka terdaftar di halaman manual inttypes.h.
Secara pribadi, saya hanya akan memberikan nilai unsigned longatau longmenyukai jawaban yang direkomendasikan. Jika Anda menggunakan C99, maka Anda dapat (dan harus, tentu saja) cor untuk unsigned long longatau long longdan menggunakan %lluatau %lldformat masing-masing.
%zddengan size_tadalah perilaku undefined karena signedness mismatch (C99 7.19.6.1 # 9). Pasti begitu %zu.
%zddengan size_tperilaku yang tidak terdefinisi dari paragraf itu atau dari yang lain. Pada kenyataannya, definisi %zdalam # 7 secara eksplisit memungkinkan %ddengan size_tdan 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:
printf("%jd\n", (intmax_t)x);
Untuk mencetak size_t:
printf("%zu\n", x);
Untuk mencetak ssize_t:
printf("%zd\n", x);
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 longdan pustaka standar Anda mendukung %lld, Anda dapat dengan yakin mengharapkan yang akan menggantikannya intmax_t. Tetapi jika tidak, Anda harus kembali ke long, yang akan gagal pada beberapa implementasi lain karena terlalu kecil.
ssize_tmemiliki ukuran yang sama size_t, jadi kode yang benar-benar portabel harus mengubahnya menjadi intmax_tdan mencetak %jdseperti off_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.
off_tselalu longitu akan membuatnya 32-bit (bahkan 64-bit Windows menggunakan 32-bit untuk long).
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.
Anda ingin menggunakan makro pemformatan dari inttypes.h.
Lihat pertanyaan ini: String format platform silang untuk variabel tipe size_t?
off_tjenis lebih besar dari pointer pada sistem 32-bit yang mendukung file besar (yang paling 32-bit sistem hari ini).
Melihat di man 3 printfLinux, OS X, dan OpenBSD semuanya menunjukkan dukungan %zuntuk size_tdan %tuntuk ptrdiff_t(untuk C99), tetapi tidak satupun yang menyebutkan off_t. Saran di alam liar biasanya menawarkan %ukonversi off_t, yang "cukup benar" sejauh yang saya tahu (keduanya unsigned intdan off_tbervariasi secara identik antara sistem 64-bit dan 32-bit).
unsigned intdan 64-bit off_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 zatau jmenandai 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 panjang size_tpada platform Anda kemudian pilih salah satu dari mereka:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Dan saya sarankan menggunakan stdinttipe daripada tipe data mentah untuk konsistensi.
%zudapat digunakan untuk mencetak size_tnilai. Satu harus pasti tidak resor untuk menggunakan uint32_t/ uint64_tformat yang specifier untuk mencetak size_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.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
long longtidak ada dalam standar C ++, dan dengan demikian bersifat non-portabel.
fopen,fseek, dll di Mac OS X.off_tdigunakan untuk offset.