Platformdan bağımsız size_t c biçimindeki biçim belirticileri?


86

size_tC türünde bir değişken yazdırmak istiyorum, ancak size_tfarklı mimarilerdeki farklı değişken türlerine diğer ad verildiği görülüyor . Örneğin, bir makinede (64 bit) aşağıdaki kod herhangi bir uyarı vermez:

ancak diğer makinemde (32 bit) yukarıdaki kod aşağıdaki uyarı mesajını veriyor:

uyarı: '% ld' biçimi 'long int *' türünü bekler, ancak bağımsız değişken 3'ün türü 'size_t *'

Bunun işaretçi boyutundaki farklılıktan kaynaklandığından şüpheleniyorum, bu nedenle 64 bit makinemde size_ta long int( "%ld") olarak adlandırılırken 32 bit makinemde size_tbaşka bir türe diğer ad verilir.

Özellikle için bir format tanımlayıcı var mı size_t?


1
Uyarı mesajınız kodla eşleşmiyor. Uyarı işaretçilerden bahsediyor, kodunuzda hiç yok. Bazılarını bir &yerden kaldırdın mı?
Jens

İşaretçiler mi? Hayır, işaretçiler hakkında herhangi bir uyarı almıyorum, aslında bu kodu hangi makinede çalıştırdığıma bağlı olarak bazen hiç uyarı almıyorum. Aşağıdaki test kodunu deneyin: #include <stdio.h> int main () {size_t size = 1; printf ("boyut% ld", boyut); dönüş 0; }
Ethan Heilman


1
@EthanHeilman O senin uyarıları demek aslında bahsediyordur warning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *'muhtemelen zaman gerektiğini söyleyerek warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t'. scanf()Bu uyarıları aldığınızda bunun yerine belki kullanıyor muydunuz?
RastaJedi

Yanıtlar:


123

Evet: zuzunluk değiştiriciyi kullanın :

Kullanılabilen diğer uzunluk değiştiriciler hh(for char), h(for short), l(for long), ll(for long long), j(for intmax_t), t(for ptrdiff_t) ve L(for long double). C99 standardı §7.19.6.1 (7) 'ye bakın.


zd ve zu arasındaki fark nedir? Zd'nin ondalık olduğunu anlıyorum, ama imzalı mı, eğer öyleyse zd'nin imzalanması işleri nasıl etkiliyor?
Ethan Heilman

1
A size_tve an arasındaki farktır ssize_t; ikincisi nadiren kullanılır.
Adam Rosenfield

26
Doğru, bu durumda kullanmalısınız %zuçünkü argüman işaretsizdir.
cafe

Mevcut diğer seçenekler printf kılavuz sayfasında açıklanmıştır: linux.die.net/man/3/printf
INS

9
@detly: Hayır, zuzunluk değiştirici C89 / C90'ın bir parçası değil. C89 uyumlu kodu hedefliyorsanız, yapabileceğiniz en iyi şey, bunun yerine uzunluk değiştiriciyi çevirmek unsigned longve kullanmaktır l, örneğin printf("the size is %lu\n", (unsigned long)size);; hem C89'u hem de size_tdaha büyük sistemleri desteklemek daha longzordur ve bir dizi önişlemci makrosunun kullanılmasını gerektirir.
Adam Rosenfield

45

Evet var. It %zu(ANSI C99 belirtildiği gibi).

Not size_tBöylece, işaretsiz olan %ldyanlış uzunluğu katsayısının düzeltilmesi, ve yanlış format dönüştürme belirteci: iki yanlıştır. Merak durumda, %zdiçindir ssize_t(imzalandığı).


1

MSDN , Visual Studio'nun 32 ve 64 bit platformlarda taşınabilir kod için "I" önekini desteklediğini söylüyor.


6
MS'e özgüdür ve standart uyumlu değildir, bu nedenle platformdan bağımsız değildir
phuclv

@phuclv Gerçekten. Ve gerçekten - cevabın önerdiği gibi - 'taşınabilir' diyorsa, MS hakkında bildiğimden daha da kötü. Beni şaşırtacağından değil ... Olumsuz oy verebilecek biri değilim çünkü birisi bir şeyi denemek ve cevaplamak için çaba sarf etti ama yine de bu cevap sadece yanlış. Ah, sanırım buradaki 'taşınabilir' fikrini anlıyorum. Hem 32 bit hem de 64 bit için çalıştığını söylemelidir. Ama elbette olur.
Pryftan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.