सी में प्रिंटफ () और पुट () के बीच क्या अंतर है?


176

मैं जानता हूँ कि आप के साथ मुद्रित कर सकते हैं printf()और puts()। मैं यह भी देख सकता हूं कि printf()आप चर को प्रक्षेपित करने और प्रारूपण करने की अनुमति देते हैं।

का puts()केवल एक आदिम संस्करण है printf()। क्या इसे printf()स्ट्रिंग इंटरपोल के बिना हर संभव उपयोग किया जाना चाहिए ?



47
पुट के बजाय प्रिंटफ का उपयोग करने पर बस एक नोट: कभी, कभी printf(variable)एक स्ट्रिंग को प्रिंट करने के लिए। का प्रयोग करें puts(variable)या printf("%s', variable)। चर प्रारूप स्ट्रिंग का उपयोग करने में सुरक्षा जोखिम है: यदि चर को किसी हमलावर द्वारा लिखा जा सकता है तो वे प्रारूप स्ट्रिंग का उपयोग करके कार्यक्रम पर हमला कर सकते हैं।
ज़ैन लिंक्स

जवाबों:


141

putsकी तुलना में सरल है, printfलेकिन इस बात से अवगत रहें कि पूर्व स्वचालित रूप से एक नई पंक्ति जोड़ता है। यदि वह नहीं है जो आप चाहते हैं, तो आप fputsअपने स्ट्रिंग को स्टडआउट या उपयोग कर सकते हैं printf


8
मुझे लगता है कि आउटपुट स्ट्रिंग में अतिरिक्त चर जोड़ने के लिए अतिरिक्त तर्कों का उल्लेख करना भी महत्वपूर्ण है।
Erutan409

99

(यह ज़ैन लिंक्स की एक टिप्पणी में बताया गया है, लेकिन मुझे लगता है कि यह एक योग्य है - यह देखते हुए कि स्वीकृत उत्तर का उल्लेख नहीं है)।

के बीच आवश्यक अंतर puts(mystr);और printf(mystr);है कि बाद में तर्क एक के रूप में व्याख्या की जाती है स्वरूपण स्ट्रिंग । यदि स्ट्रिंग में कोई नियंत्रण वर्ण %नहीं है (तो ( जोड़े गए न्यूलाइन को छोड़कर) परिणाम अक्सर एक ही होगा ( लेकिन यदि आप उस पर भरोसा नहीं कर सकते हैं (यदि mystrशाब्दिक के बजाय एक चर है) तो आपको इसका उपयोग नहीं करना चाहिए ।

इसलिए, यह आम तौर पर खतरनाक-और वैचारिक रूप से गलत है - एक गतिशील स्ट्रिंग को एकल तर्क के रूप में पास करने के लिए printf:

  char * myMessage;
  // ... myMessage gets assigned at runtime, unpredictable content
  printf(myMessage);  // <--- WRONG! (what if myMessage contains a '%' char?) 
  puts(myMessage);    // ok
  printf("%s\n",myMessage); // ok, equivalent to the previous, perhaps less efficient

वही fputsबनाम पर लागू होता है fprintf(लेकिन fputsनई पंक्ति नहीं जोड़ता है)।


किस तरह से उपयोग printf()करना कम कुशल होगा? चलने के समय पर? संकलन के समय?
फ्रैंकलिन

10
@franklin रनटाइम पर, क्योंकि printfप्रारूप स्ट्रिंग को पार्स करने की आवश्यकता है। हालांकि, यह आम तौर पर अप्रासंगिक होना चाहिए। इसके अलावा, एक चतुर कंपाइलर इसे ऑप्टिमाइज़ कर सकता है, और printfputs
बजे

33

प्रारूपण के अलावा, putsयदि कोई सफल या EOFअसफल है तो एक अप्रतिदेय पूर्णांक लौटाता है ; जबकि printfमुद्रित वर्णों की संख्या लौटाता है (अनुगामी नल सहित नहीं)।


16

सरल मामलों में, संकलक कॉल को कॉल में परिवर्तित printf()करता है puts()

उदाहरण के लिए, निम्नलिखित कोड विधानसभा कोड मैं अगले शो के लिए संकलित किया जाएगा।

#include <stdio.h>
main() {
    printf("Hello world!");
    return 0;
}
push rbp
mov rbp,rsp
mov edi,str.Helloworld!
call dword imp.puts
mov eax,0x0
pop rbp
ret

इस उदाहरण में, मैंने जीसीसी संस्करण 4.7.2 का उपयोग किया और स्रोत को संकलित किया gcc -o hello hello.c


9
और नई लाइन के बारे में क्या है जो स्टडआउट में जगह बनाती है?
जुबेरगू

1
यह होना चाहिए printf("Hello world!\n");कि वास्तव में अनुवाद किया गया है कि डालता है। चूंकि यह एक पुराना संदेश है, इसलिए मैं इसे स्वयं संपादित करूंगा।
राफेल अल्मीडा

2
C कोड संकलित करने के बाद आपने असेंबली कोड कैसे पढ़ा?
कोरे तुगय

3
@KorayTugay: -save-tempsgcc के लिए विकल्प यह है कि
schaiba

आप बाइनरी को डिसाइड करने के लिए gdb जैसे टूल का भी इस्तेमाल कर सकते हैं।
इवान कालॉयनोव

10

सही, के printfएक अधिक शक्तिशाली संस्करण के रूप में सोचा जा सकता है putsprintfकरने की क्षमता प्रदान प्रारूप जैसे उत्पादन का उपयोग कर प्रारूप विनिर्देशक के लिए चर %s, %d, %lf, आदि ...


10

मेरे अनुभव में, प्रारूप स्ट्रिंग की परवाह किए बिना printf()अधिक कोड में हल्स puts()

अगर मुझे प्रारूपण की आवश्यकता नहीं है, तो मैं उपयोग नहीं करता हूं printf। हालांकि, की तुलना में बहुत तेजी से काम fwriteकरने के लिए ।stdoutputs

static const char my_text[] = "Using fwrite.\n";
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout);

नोट: प्रति टिप्पणी, '\ 0' पूर्णांक स्थिरांक है। सही अभिव्यक्ति को sizeof(char)टिप्पणियों द्वारा इंगित किया जाना चाहिए ।


2
"स्ट्रेटआउट को राइटिंग पुट की तुलना में बहुत तेजी से काम करता है।" - संभवतः इसका क्या कारण हो सकता है?
एंटनी हैचकिंस

6
@AntonyHatchkins यह आमतौर पर "बहुत अधिक" तेज नहीं है। पुट (), हालांकि, अपने स्ट्रिंग पर हर बार एक स्ट्रलेन () कॉल करना पड़ता है, जबकि यदि आकार राइटाइट के साथ जाना जाता है () तो इसे टाला जा सकता है। एक प्रदर्शन अंतर के लिए यह एकमात्र वास्तविक कंट्रीब्यूटर है।
जानकार

8
यह उत्तर गलत है। '\0'प्रकार है int, इसलिए अधिकांश सिस्टम पर यह प्रिंट होगा Using fwrit। यदि आप 1 कम बाइट प्रिंट करना चाहते हैं, तो बस 1. का उपयोग करें sizeof (char), जो कि आप यहाँ जो भी करने की संभावना है, वह 1. होने की गारंटी है।
ब्रैडली गगन

8
int puts(const char *s);

डालता है () स्ट्रिंग एस और एक अनुगामी newline को stdout को लिखता है।

int printf(const char *format, ...);

फ़ंक्शन प्रिंटफ़ () आउटपुट को स्टडआउट में लिखता है, एक प्रारूप स्ट्रिंग के नियंत्रण के तहत जो निर्दिष्ट करता है कि आउटपुट के लिए बाद के तर्क कैसे परिवर्तित होते हैं।

मैं इस अवसर का उपयोग आपको दस्तावेज़ पढ़ने के लिए कहने के लिए करूँगा।


5

प्रिंटफ () फ़ंक्शन का उपयोग स्क्रीन पर स्ट्रिंग और चर दोनों को प्रिंट करने के लिए किया जाता है जबकि पुट () फ़ंक्शन केवल आपको अपनी स्क्रीन पर केवल एक स्ट्रिंग प्रिंट करने की अनुमति देता है।


2

putsसरल विकल्प है और अंत में एक नई लाइन जोड़ता है और printfएक स्वरूपित स्ट्रिंग से आउटपुट लिखता है।

puts और के लिए प्रलेखन देखें printf

मैं केवल इसका उपयोग करने की सलाह printfदूंगा क्योंकि यह स्विचिंग विधि की तुलना में अधिक सुसंगत है, अर्थात यदि आप डिबगिंग कर रहे हैं, तो यह सभी प्रिंटफ़ की तुलना में putsऔर खोजने के लिए कम दर्दनाक है printf। ज्यादातर बार आप अपने प्रिंटआउट में एक चर का उत्पादन करना चाहते हैं, इसलिए putsज्यादातर उदाहरण कोड में उपयोग किया जाता है।


1

जब तुलना puts()और printf(), भले ही उनकी स्मृति खपत लगभग समान हो, puts()की तुलना में अधिक समय लगता है printf()


कृपया अपने उत्तर में कुछ स्पष्टीकरण जोड़ें, ताकि अन्य इससे सीख सकें - क्या आपके पास उस दावे के लिए विश्वसनीय स्रोत हैं? या इस अंतर को समझाने के कुछ कारण?
निको हसे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.