Ben gibi türlerini yazdırmak çalışıyorum off_t
ve 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_t
ve 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 z
size_t ve t
benzeri ifadesi ptrdiff_t için
printf("%zu %td", size, ptrdiff);
Ama benim sayfam bazı eski kütüphanelerinkinden farklı bir karakter z
kullandığı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_t
ve int8_t
bir stdint.h
baş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 long
ya da long
istiyorum. Eğer, o zaman (ve reddedilmesi gereken, tabii ki) döküm için C99 kullanıyorsanız unsigned long long
veya long long
ve kullanımı %llu
veya %lld
sırasıyla biçimleri.
%zd
bir ile size_t
olan tanımsız davranış nedeniyle signedness uyumsuzluğu (C99 7.19.6.1 # 9) için. Öyle olmalı %zu
.
%zd
bir ile size_t
o paragraftan ya da başka gelen tanımsız davranış olur. Aslında, tanımı %z
içinde 7. açıkça tanır %d
ile size_t
ve 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 long
ve 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
, %jd
tı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_t
her zaman long
32 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_t
Tipi (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 printf
Linux, OS X ve tüm gösteri için destek OpenBSD'de %z
için size_t
ve %t
için ptrdiff_t
(C99 için), ancak bu söz hiçbiri off_t
. Vahşi Öneriler genelde sunuyoruz %u
için dönüşüm off_t
"doğru yeterince" bildiğim kadarıyla (her ikisi de söyleyebilir gibidir, unsigned int
ve off_t
64-bit ve 32-bit sistemler arasında aynı değişir).
unsigned int
ve 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 z
veya j
bayraklar ve platformdan bağımsız görünmüyorlar ).
Standart açıkça tam veri uzunluğu demez size_t
ben ilk uzunluğunu kontrol etmelidir önermek böylece, size_t
daha sonra bunlardan birini seçmek sizin platformda:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Ve stdint
tutarlılık için ham veri türleri yerine türleri kullanmanızı öneririm .
%zu
yazdı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_t
format 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 long
C ++ standardında mevcut değil ve bu nedenle doğası gereği taşınabilir değildir.
fopen
,fseek
vb Mac OS X'teoff_t
ofset için kullanılır.