मुझे off_t और size_t जैसे प्रकार कैसे प्रिंट करने चाहिए?


148

मैं जैसे off_tऔर मुद्रित करने की कोशिश कर रहा हूँ size_tprintf() पोर्टेबल के लिए सही प्लेसहोल्डर क्या है ?

या क्या उन चरों को छापने का कोई अलग तरीका है?


2
@devin: मेरा मानना है कि का उपयोग करते समय मैं उस प्रकार मिल गया है fopen, fseek, मैक ओएस एक्स पर आदि off_tके लिए ऑफसेट प्रयोग किया जाता है।
जॉर्ज शॉली

जवाबों:


112

आप zsize_t के लिए और tजैसे ptrdiff_t के लिए उपयोग कर सकते हैं

printf("%zu %td", size, ptrdiff);

लेकिन मेरा मेन्यू कहता है कि कुछ पुराने पुस्तकालय ने इसके इस्तेमाल से zहतोत्साहित किया है। फिर भी, यह मानकीकृत है (C99 मानक द्वारा)। उन लोगों के लिए intmax_tऔर int8_tकी stdint.hऔर इतने पर, वहाँ मैक्रो आप उपयोग कर सकते हैं, जैसे एक और उत्तर कहा हैं:

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

वे के पेज में सूचीबद्ध हैं inttypes.h

व्यक्तिगत रूप से, मैं सिर्फ एक unsigned longया longदूसरे जवाब की सिफारिश करने के लिए मान डालूंगा। आप, तो आप (और, ज़ाहिर है चाहिए) डाली कर सकते हैं C99 का उपयोग करते हैं unsigned long longया long longऔर प्रयोग %lluया %lldक्रमशः प्रारूपों।


2
off_t वास्तव में मेरे सिस्टम पर एक लंबा हस्ताक्षर है।
जॉर्ज शॉर्ली

2
मुझे लगता है कि मैन पेज Z (अपरकेस) के उपयोग को हतोत्साहित करता है जिसका उपयोग libc5 द्वारा किया गया था। यह z (लोअरकेस) को हतोत्साहित नहीं करता है।
ड्रेमन

12
का उपयोग करते हुए %zdएक साथ size_tहै अपरिभाषित व्यवहार signedness बेमेल (C99 7.19.6.1 # 9) की वजह से। यह होना ही चाहिए %zu
जेन्स

7
खैर, फिर off_t कैसे प्रिंट करें?
जॉनीटेक्स

3
@Jens मैं कैसे नहीं दिख रहा है %zdके साथ एक size_tहै कि पैरा से या किसी अन्य से अपरिभाषित व्यवहार हो जाता है। वास्तव में, %z# 7 की परिभाषा स्पष्ट रूप %dसे size_tऔर संबंधित हस्ताक्षरित प्रकार के साथ अनुमति देती है , और the6.2.5 # 9 स्पष्ट रूप से अहस्ताक्षरित प्रकारों के मूल्यों का उपयोग करने की अनुमति देता है जहां संबंधित हस्ताक्षरित प्रकार की अपेक्षा की जाती है, जब तक कि मूल्य एक मान्य नॉनगेटिव मूल्य है हस्ताक्षरित प्रकार।
चोर्टोस -2 2

108

मुद्रित करने के लिए off_t:

printf("%jd\n", (intmax_t)x);

मुद्रित करने के लिए size_t:

printf("%zu\n", x);

मुद्रित करने के लिए ssize_t:

printf("%zd\n", x);

C99 मानक में 7.19.6.1/7, या कोडिंग प्रारूप के अधिक सुविधाजनक POSIX दस्तावेज देखें:

http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

यदि आपका कार्यान्वयन उन फ़ॉर्मेटिंग कोडों का समर्थन नहीं करता है (उदाहरण के लिए क्योंकि आप C89 पर हैं), तो आपके पास थोड़ी सी समस्या है क्योंकि AFAIK में C89 में पूर्णांक प्रकार नहीं हैं जिनमें कोड स्वरूपण हैं और बड़े होने की गारंटी है इन प्रकारों के रूप में। इसलिए आपको कुछ कार्यान्वयन-विशिष्ट करने की आवश्यकता है।

उदाहरण के लिए यदि आपका कंपाइलर है long longऔर आपका मानक पुस्तकालय समर्थन करता है %lld, तो आप विश्वास के साथ उम्मीद कर सकते हैं कि इसकी जगह काम करेगा intmax_t। लेकिन अगर ऐसा नहीं होता है, तो आपको वापस गिरना longहोगा, जो कुछ अन्य कार्यान्वयन पर विफल होगा क्योंकि यह बहुत छोटा है।


3
यह अब तक का बेहतर जवाब है, मैं अहस्ताक्षरित size_t के लिए% zu का उपयोग करने के बारे में भूल गया होगा। और intmax_t के लिए कास्टिंग किसी भी मंच पर off_t जो कुछ भी है के लिए एक महान समाधान है।
पीटर कॉर्ड्स

2
POSIX गारंटी नहीं देता है कि ssize_tइसका आकार एक जैसा है size_t, इसलिए वास्तव में पोर्टेबल कोड को इसे उसी तरह बदलना चाहिए intmax_tऔर प्रिंट करना चाहिए %jdजैसे कि off_t
nwellnhof

off_t का आकार लंबे समय तक हो सकता है और परिभाषित के आधार पर परिवर्तनशील हो सकता है ... विज़ुअल स्टूडियो इस के साथ चेतावनी भी देता है "C4477: '_snprintf_s': स्वरूप स्ट्रिंग '% jd' के लिए'__int64 'प्रकार के तर्क की आवश्यकता होती है, लेकिन परिवर्तनशील तर्क 1 टाइप 'off_t' "... एक ट्रुअली पोर्टेबल तरीका है प्रिंटफ ("% lld \ n ", (लंबे समय तक) x);
इरिस्क्रीन 16

5

Microsoft के लिए, उत्तर अलग है। VS2013 काफी हद तक C99 के अनुरूप है लेकिन "[t] वह hh, j, z, और t लंबाई उपसर्ग का समर्थन नहीं करता है।" Size_t "के लिए, 32-बिट प्लेटफ़ॉर्म पर अहस्ताक्षरित __int32, 64-बिट प्लेटफ़ॉर्म पर अहस्ताक्षरित __int64" प्रकार स्पेसर ओ, यू, एक्स, या एक्स के साथ "उपसर्ग I (पूंजी आंख) का उपयोग करें" देखें। VS2018 आकार विनिर्देश

जैसा कि off_t के लिए है, यह वीसी में शामिल है जब तक कि \ sys \ types.h शामिल नहीं हैं।


ध्यान दें कि यदि off_tहमेशा longऐसा होता है तो यह 32-बिट (64-बिट विंडोज के लिए 32-बिट का उपयोग करता है long) कर देगा।
sourcejedi

3

C का कौन सा संस्करण उपयोग कर रहे हैं?

C90 में, मानक अभ्यास पर हस्ताक्षर किए गए या लंबे समय तक, उचित रूप में, और तदनुसार मुद्रित करने के लिए डाली जाती है। मैंने size_t के लिए% z देखा है, लेकिन हार्बिसन और स्टील ने इसका उल्लेख printf () के तहत नहीं किया है, और किसी भी स्थिति में जो आपको ptrdiff_t या जो भी मदद नहीं करेगा।

C99 में, विभिन्न _t प्रकार अपने स्वयं के प्रिंटफ मैक्रोज़ के साथ आते हैं, इसलिए कुछ ऐसा है जो "Size is " FOO " bytes." मुझे विवरण नहीं पता है, लेकिन यह काफी बड़े संख्यात्मक प्रारूप का हिस्सा है जिसमें फ़ाइल शामिल है।


3

आप inttypes.h से स्वरूपण मैक्रो का उपयोग करना चाहते हैं।

यह प्रश्न देखें: type size_t के चर के लिए प्लेटफ़ॉर्म प्रारूप स्ट्रिंग?


यह मानते हुए कि off_t एक हस्ताक्षरित, सूचक-आकार का int है (मुझे नहीं पता कि सटीक परिभाषा क्या है) ptrdiff_t की तरह तो आप PRIdPTR या PRIiPTR का उपयोग करेंगे।
माइकल बूर

11
off_tप्रकार किसी भी 32-बिट सिस्टम पर एक सूचक है कि बड़ी फ़ाइलों (जो सबसे अधिक 32-बिट सिस्टम इन दिनों है) का समर्थन करता है से बड़ा है।
डिट्रिच एप

1
@DietrichEpp: वास्तव में, यह उससे भी बदतर है; कई 32-बिट सिस्टम में off_t और off64_t दोनों होते हैं, और फ़ीचर मैक्रोज़ off_t के आधार पर वास्तव में off64_t हो सकता है।
सैमबी

1

को देखते हुए man 3 printfलिनक्स, ओएस एक्स पर, और के लिए सभी शो समर्थन OpenBSD %zके लिए size_tऔर %tके लिए ptrdiff_t(C99 के लिए), लेकिन उन में से कोई भी उल्लेख off_t। जंगली में सुझाव आमतौर पर की पेशकश %uके लिए रूपांतरण off_tहै, जो "सही पर्याप्त" जहाँ तक मैं (दोनों बता सकते है unsigned intऔर off_t64-बिट और 32-बिट सिस्टम के बीच समान रूप से भिन्न हो)।


1
मेरे सिस्टम (OS X) में 32-बिट unsigned intऔर 64-बिट है off_t। इसलिए कास्ट डेटा खो जाएगा।
डिट्रीच एप

-3

मैंने इस पोस्ट को कम से कम दो बार देखा, क्योंकि स्वीकृत उत्तर मेरे लिए याद रखना मुश्किल है (मैं शायद ही कभी उपयोग करता हूं zया jझंडे और उन्हें लगता है कि मंच स्वतंत्र नहीं है )।

मानक कहते हैं कभी नहीं स्पष्ट रूप से की सटीक डेटा लंबाई size_t, तो मैं सुझाव है कि आप पहले लंबाई की जाँच करनी चाहिए size_tअपने मंच पर तो उनमें से एक का चयन करें:

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

और मैं सुझाव देता हूं कि stdintनिरंतरता के लिए कच्चे डेटा प्रकारों के बजाय प्रकारों का उपयोग करें ।


1
C99 और C11 के लिए, मानक स्पष्ट रूप से बताता है कि %zuइसका उपयोग size_tमूल्यों को प्रिंट करने के लिए किया जा सकता है । किसी को प्रिंट करने के लिए निश्चित रूप सेuint32_t / uint64_tफॉर्मेट स्पेसियर का उपयोग करने का सहारा नहीं लेना चाहिए size_t, क्योंकि इस बात की कोई गारंटी नहीं है कि वे प्रकार संगत हैं।
ऑटिस्टिक

-4

जैसा कि मुझे याद है, इसे करने का एकमात्र पोर्टेबल तरीका है, परिणाम को "अहस्ताक्षरित लंबे समय तक int" और उपयोग के लिए डालना है %lu

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));

1
"% Lu" होना चाहिए, क्योंकि रूपांतरण से पहले लंबाई संशोधक आना चाहिए।
dwc

1
उदाहरण के लिए off_t एक लंबे समय से हस्ताक्षरित है।
जॉर्ज स्कोली

@ GeorgSchölly - तब आपने एक कॉनड्रोम मारा है, क्योंकि long longसी ++ मानक में मौजूद नहीं है, और इस प्रकार स्वाभाविक रूप से गैर-पोर्टेबल है।
जेम्स कर्रान

-9

off_t के लिए "% zo" का उपयोग करें। (अष्टक) या दशमलव के लिए "% zu"।


आप ऑक्टल में फाइल की भरपाई क्यों करना चाहेंगे?
पूली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.