प्रिंट फॉर्मेट निर्दिष्ट करता है uint32_t और size_t के लिए


101

मेरे पास निम्नलिखित है

size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]\n", i, k);

संकलन करते समय मुझे निम्नलिखित चेतावनी मिली है:

format ‘%lu expects type long unsigned int’, but argument has type uint32_t

जब मैंने स्प्लिंट का उपयोग करके इसे चलाया तो मुझे निम्नलिखित मिला:

Format argument 1 to printf (%u) expects unsigned int gets size_t: k

किसी भी सलाह के लिए बहुत धन्यवाद,


2
C89 या uint32_tसे समर्थन नहीं करता है ; यदि आप उन प्रकारों का उपयोग करना चाहते हैं, तो आपको C89 में अपग्रेड करना चाहिए। एक विस्तार के रूप में, यह संभावना है कि जीसीसी आपको उनका उपयोग करने की अनुमति देता है, लेकिन C89 के पास ऐसा कोई समर्थन नहीं था। <stdint.h><inttypes.h>
जोनाथन लेफलर

10
और आधिकारिक सी 99 प्रारूप संशोधक size_t'जेड' है, जैसा कि अंदर है "%zu"
जोनाथन लेफलर


मेरा मानना ​​है कि @ केनी का जवाब सबसे अच्छा है uint32_t, लेकिन इसमें कमी है size_t। @ u0b34a0f6ae के उत्तर में दोनों शामिल हैं।
jww

जोनाथन
लेफ़लर

जवाबों:


28

लगता है जैसे आप (संभवतः 64 बिट्स) size_tके समान होने की उम्मीद कर रहे हैं unsigned longजब यह वास्तव में एक unsigned int(32 बिट्स) है। %zuदोनों मामलों में उपयोग करने का प्रयास करें ।

मैं हालांकि पूरी तरह से निश्चित नहीं हूं।


1
संकलन करते समय कोई चेतावनी नहीं। हालाँकि, चल रहे स्प्लिंट मुझे निम्नलिखित मिलते हैं: 1) प्रिंटफ (% u) को उम्मीद है कि अहस्ताक्षरित int को uint32_t मिलता है: i 2) प्रिंटफ (% u) को उम्मीद है कि अहस्ताक्षरित int size_t: k
ant2009

स्प्लिट जैसी आवाज़ बस पांडित्य है, फिर। यह शायद स्रोत कोड के प्रकारों के नाम से दूर जा रहा है और उन्हें एहसास नहीं है कि वे समकक्ष हैं। मुझे आश्चर्य है कि यह @ केनीटीएम के जवाब के साथ क्या करेगा ... यह निश्चित रूप से अधिक पोर्टेबल होना चाहिए।
कोगव्हील

3
स्प्लिंट वास्तव में सही काम कर रहा है। सिर्फ इसलिए कि int32_tहोने वाला intअपने संकलक पर / मंच मतलब यह नहीं है कि यह नहीं हो सकता है longएक और पर। उसी के लिए size_t। यह वास्तव में अपने रास्ते से बाहर जा रहा है और इस पोर्टेबिलिटी बग का पता लगाने के लिए और अधिक काम कर रहा है, क्योंकि कम्पाइलर की तरह ही प्राकृतिक जांच सिर्फ टाइम्डफ को सम्मानित करना होगा।
आर .. गिटहब स्टॉप हेल्पिंग आईसीई

4
-1, क्षमा करें यह पोर्टेबल नहीं है। इसके लिए केवल यह आवश्यक है कि प्रारूप निर्दिष्ट करें और प्रकार सहमत हों, और आप हमेशा इसे सच बनाने के लिए डाल सकते हैं। लंबा कम से कम 32 बिट्स है, इसलिए %luएक साथ (unsigned long)kहमेशा सही होता है। size_tमुश्किल है, यही वजह है कि %zuC99 में जोड़ा गया था। यदि आप इसका उपयोग नहीं कर सकते हैं, तो इसे उसी तरह से व्यवहार करें k( longC89 में सबसे बड़ा प्रकार है, size_tबड़ा होने की संभावना नहीं है)।
u0b34a0f6ae

139

प्रयत्न

#include <inttypes.h>
...

printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);

zलंबाई के रूप में ही की एक पूर्णांक का प्रतिनिधित्व करता है size_t, और PRIu32मैक्रो, C99 हेडर में निर्धारितinttypes.h , एक अहस्ताक्षरित 32-बिट पूर्णांक प्रतिनिधित्व करता है।


3
@robUK: हेह। मेरा सुझाव है कि आप विभाजन के लिए एक बग दर्ज करें।
kennytm

8
यह सही जवाब है। हालांकि मेरी व्यक्तिगत सिफारिश है, बस उदाहरण के लिए, डाली printf( "%lu", (unsigned long )i )। अन्यथा एक प्रकार के परिवर्तन के कारण कोड में सभी चेतावनियों के साथ बाद में समाप्त हो जाता है।
डमी 00001 19

1
यह सही जवाब है। मैं स्प्लिट के लिए बग दर्ज करने के बारे में केनीटीएम से सहमत हूं। वैसे, "% zu" size_t के लिए उचित प्रारूप है। आपको मुद्रण आकार_ के लिए किसी भी PRI * मैक्रोज़ की आवश्यकता नहीं है।
आर .. गिटहब स्टॉप हेल्पिंग ICE

1
अगर मुझे सही ढंग से याद है कि% z, C99 है, और प्रश्न में उसने 'C89' लिखा है।
एल्कोर

8
@alcor हाँ उन्होंने C89 (जाहिरा तौर पर जिस gcc संकलक ध्वज का उपयोग कर रहे हैं) को रखा था, लेकिन वे uint32_tवास्तव में यह C99 कोड का उपयोग कर रहे हैं, और इस तरह संकलित किया जाना चाहिए।
कॉलिन डी बेनेट

28

इसके लिए केवल यह आवश्यक है कि प्रारूप निर्दिष्ट करें और प्रकार सहमत हों, और आप हमेशा इसे सच बनाने के लिए डाल सकते हैं। longकम से कम 32 बिट्स है, इसलिए %luएक साथ (unsigned long)kहमेशा सही होता है:

uint32_t k;
printf("%lu\n", (unsigned long)k);

size_tमुश्किल है, यही वजह है कि %zuC99 में जोड़ा गया था। यदि आप इसका उपयोग नहीं कर सकते हैं, तो इसे उसी तरह से व्यवहार करें k( longC89 में सबसे बड़ा प्रकार है, size_tबड़ा होने की संभावना नहीं है)।

size_t sz;
printf("%zu\n", sz);  /* C99 version */
printf("%lu\n", (unsigned long)sz);  /* common C89 version */

यदि आपको जिस प्रकार से आप पास कर रहे हैं, उसके लिए फॉर्मेट स्पेसर सही नहीं मिलता है, तो आप printfसरणी से बाहर बहुत अधिक या बहुत कम मेमोरी पढ़ने के बराबर करेंगे। जब तक आप स्पष्ट कास्ट का उपयोग प्रकारों के मिलान के लिए करते हैं, तब तक यह पोर्टेबल है।


17

आप मैक्रो पंचायती राज उपयोग करने के लिए * नहीं करना चाहते हैं, मुद्रण के लिए एक और दृष्टिकोण किसी भी पूर्णांक प्रकार के कलाकारों के लिए है intmax_tया uintmax_tऔर उपयोग "%jd"या %ju, क्रमशः। यह POSIX (या अन्य OS) प्रकारों के लिए विशेष रूप से उपयोगी है, जिनमें PRI * मैक्रोज़ परिभाषित नहीं है, उदाहरण के लिए off_t

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