Ben gibi türlerini yazdırmak çalışıyorum off_tve size_t. printf() Taşınabilir olan için doğru yer tutucu nedir ?
Yoksa bu değişkenleri yazdırmanın tamamen farklı bir yolu var mı?
Ben gibi türlerini yazdırmak çalışıyorum off_tve size_t. printf() Taşınabilir olan için doğru yer tutucu nedir ?
Yoksa bu değişkenleri yazdırmanın tamamen farklı bir yolu var mı?
Yanıtlar:
Sen kullanabilirsiniz zsize_t ve tbenzeri ifadesi ptrdiff_t için
printf("%zu %td", size, ptrdiff);
Ama benim sayfam bazı eski kütüphanelerinkinden farklı bir karakter zkullandığını ve kullanılmasını caydırdığını söylüyor . Bununla birlikte, standartlaştırılmıştır (C99 standardına göre). Olanlar için intmax_tve int8_tbir stdint.hbaşka cevabı dediğim gibi ve benzeri kullanabileceğiniz makrolar vardır:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Bunlar sayfalarında listelenmiştir inttypes.h.
Şahsen ben sadece değerleri başka bir yanıt tavsiye gibi unsigned longya da longistiyorum. Eğer, o zaman (ve reddedilmesi gereken, tabii ki) döküm için C99 kullanıyorsanız unsigned long longveya long longve kullanımı %lluveya %lldsırasıyla biçimleri.
%zdbir ile size_tolan tanımsız davranış nedeniyle signedness uyumsuzluğu (C99 7.19.6.1 # 9) için. Öyle olmalı %zu.
%zdbir ile size_to paragraftan ya da başka gelen tanımsız davranış olur. Aslında, tanımı %ziçinde 7. açıkça tanır %dile size_tve ilgili imzalanan türü ve değeri geçerli bir negatif olmayan bir değerdir uzun olduğunca §6.2.5 9. açıkça karşılık gelen işaretli tür beklenen imzasız türleri değerlerini kullanarak verir imzalı tip.
Yazdırmak için off_t:
printf("%jd\n", (intmax_t)x);
Yazdırmak için size_t:
printf("%zu\n", x);
Yazdırmak için ssize_t:
printf("%zd\n", x);
C99 standardında 7.19.6.1/7 veya biçimlendirme kodlarının daha uygun POSIX belgelerine bakın:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Uygulamanız bu biçimlendirme kodlarını desteklemiyorsa (örneğin C89'da olduğunuz için), AFAIK'te biraz sorun yaşarsınız, çünkü C89'da biçimlendirme kodlarına sahip ve büyük olması garanti edilen tamsayı türleri yoktur bu tür olarak. Yani uygulamaya özel bir şey yapmanız gerekiyor.
Örneğin, derleyiciniz long longve standart kitaplığınız destekliyorsa %lld, bunun yerine hizmet vermesini bekleyebilirsiniz intmax_t. Ama eğer yapmazsa, geri dönmeniz gerekir long, bu da diğer bazı uygulamalarda başarısız olur, çünkü çok küçüktür.
ssize_t, aynı boyutta olduğunu garanti etmez size_t, bu nedenle gerçekten taşınabilir kod intmax_t, %jdtıpkı gibi dönüştürülmeli ve yazdırılmalıdır off_t.
Microsoft için cevap farklı. VS2013 büyük ölçüde C99 uyumludur ancak "[h] he hh, j, z ve t uzunluk önekleri desteklenmez." Size_t "için, 32 bit platformlarda işaretsiz __int32, 64 bit platformlarda işaretsiz __int64" için o, u, x veya X tür belirteciyle I öneki (büyük göz) kullanın. Bkz. VS2013 Boyut belirtimi
Off_t için ise, VC \ include \ sys \ types.h dosyasında uzun olarak tanımlanmıştır.
off_ther zaman long32 bit (64 bit Windows bile 32 bit kullanır long) yaparsa unutmayın .
Hangi C sürümünü kullanıyorsunuz?
C90'da standart uygulama, uygun olduğu şekilde, imzalı veya imzasız uzun süre kullanmak ve buna göre yazdırmaktır. Size_t için% z gördüm, ancak Harbison ve Steele printf () altında bahsetmiyorlar ve her durumda ptrdiff_t veya herhangi bir şekilde size yardımcı olmaz.
C99'da, çeşitli _t türleri kendi printf makrolarıyla birlikte gelir, bu yüzden "Size is " FOO " bytes." ayrıntıları bilmiyorum gibi bir şey , ancak bu oldukça büyük bir sayısal format dosya içerir.
İnttypes.h dosyasından biçimlendirme makrolarını kullanmak isteyeceksiniz.
Şu soruya bakın: size_t?
off_tTipi (en 32 bit sistemler bu gün olan) büyük dosyaları destekleyen herhangi 32-bit sistemde bir işaretçi daha büyüktür.
Baktığımızda man 3 printfLinux, OS X ve tüm gösteri için destek OpenBSD'de %ziçin size_tve %tiçin ptrdiff_t(C99 için), ancak bu söz hiçbiri off_t. Vahşi Öneriler genelde sunuyoruz %uiçin dönüşüm off_t"doğru yeterince" bildiğim kadarıyla (her ikisi de söyleyebilir gibidir, unsigned intve off_t64-bit ve 32-bit sistemler arasında aynı değişir).
unsigned intve 64 bit var off_t. Böylece oyuncular verilerin kaybolmasına neden olur.
Bu yazıyı en az iki kez gördüm, çünkü kabul edilen cevabı hatırlamak zor (nadiren kullanıyorum zveya jbayraklar ve platformdan bağımsız görünmüyorlar ).
Standart açıkça tam veri uzunluğu demez size_tben ilk uzunluğunu kontrol etmelidir önermek böylece, size_tdaha sonra bunlardan birini seçmek sizin platformda:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Ve stdinttutarlılık için ham veri türleri yerine türleri kullanmanızı öneririm .
%zuyazdırmak için kullanılabileceğini açıkça belirtir size_t. Bu türlerin uyumlu olduğuna dair bir garanti olmadığından , kesinlikle bir uint32_t/ uint64_tformat belirteci kullanmak için başvurmamalıdır size_t.
Hatırladığım gibi, bunu yapmanın tek taşınabilir yolu sonucu "unsigned long int" ve kullanımı için kullanmaktır %lu.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
long longC ++ standardında mevcut değil ve bu nedenle doğası gereği taşınabilir değildir.
fopen,fseekvb Mac OS X'teoff_tofset için kullanılır.