C ++: "std :: endl" बनाम "\ n"


568

कई सी ++ पुस्तकों में इस तरह के उदाहरण कोड होते हैं ...

std::cout << "Test line" << std::endl;

... तो मैंने भी हमेशा यही किया है। लेकिन मैंने इसके बजाय काम करने वाले डेवलपर्स से बहुत सारे कोड देखे हैं:

std::cout << "Test line\n";

क्या एक के बाद एक को पसंद करने का एक तकनीकी कारण है, या यह केवल कोडिंग शैली का मामला है?


7
अच्छी व्याख्या: cppkid.wordpress.com/2008/08/27/why-i-prefer-n-to-stdendl


25
@derobert यह एक दूसरे से पुराना है
किरा

3
@ हेदीनेली वास्तव में यह है। लेकिन दूसरे एक पर जवाब मुझे थोड़ा बेहतर है, इसलिए मैंने इसे इस तरह से करने के लिए चुना। इसके अलावा, अन्य एक थोड़ा व्यापक है, भी कवर '\n'
derobert

stackoverflow.com/a/30968225/3163618 एक महत्वपूर्ण प्रदर्शन अंतर हो सकता है।
क्यूर

जवाबों:


473

अलग-अलग पंक्ति-अंत वाले वर्ण मायने नहीं रखते, मान लें कि फ़ाइल पाठ मोड में खुली है, जो कि आपको तब तक मिलती है जब तक कि आप बाइनरी के लिए नहीं पूछते। संकलित कार्यक्रम संकलित प्रणाली के लिए सही बात लिखेगा।

एकमात्र अंतर यह है कि std::endlआउटपुट बफर को फ्लश '\n'करता है , और नहीं करता है। यदि आप बफ़र को बार-बार फ्लश नहीं करना चाहते हैं, तो उपयोग करें '\n'। यदि आप करते हैं (उदाहरण के लिए, यदि आप सभी आउटपुट प्राप्त करना चाहते हैं, और प्रोग्राम अस्थिर है), उपयोग करें std::endl


24
या ::std::cerrइसके बजाय का उपयोग करने पर विचार करें ::std::coutक्योंकि यह अप्रभावित है और प्रत्येक और हर आउटपुट ऑपरेशन से भरा हुआ है।
सर्वव्यापी

142
@Omnifarious: कोई std :: cerr त्रुटियों के लिए आरक्षित होना चाहिए। दो धाराओं को एक साथ सिंक नहीं किया जाता है, इसलिए यदि आप कुछ पाठ को आउटपुट करने के लिए इसे बफ़र्ड करते हैं और cerr आउटपुट में जाएगा, तो यह एक मिश्रित मोड डिस्प्ले के परिणामस्वरूप होगा। (त्रुटियों) के लिए यह माना जाता है कि cerr का उपयोग करें और इसे (सामान्य बातचीत) के लिए डिज़ाइन किया गया है।
मार्टिन यॉर्क

23
@ लुकास: '\ n' से अधिक कोई प्लेटफॉर्म जागरूक नहीं है।
सीबी बेली

32
@ लोकीअस्तारी: मैं यह नहीं कहूंगा कि stderr"त्रुटियां" हैं। इसके बजाय, यदि आप करेंगे, तो यह नैदानिक ​​संदेशों से बाहर है। ./prog > fileकेवल सच्चे प्रोग्राम पेलोड को कहना और संग्रहीत करना संभव होना चाहिए , लेकिन कार्यक्रम सामान्य बातचीत में भी बहुत अधिक स्थिति जानकारी का उत्पादन करना पसंद कर सकता है।
केरेक एसबी

13
"कई कार्यान्वयन में, मानक आउटपुट लाइन-बफ़र्ड होता है, और '\ n' लिखने से किसी भी तरह से फ्लश होता है, जब तक कि std :: cout.sync_with_stdio (झूठा) निष्पादित नहीं किया गया था।" यहाँ से कॉपी किया गया
GuLearn

249

अंतर को निम्नलिखित द्वारा स्पष्ट किया जा सकता है:

std::cout << std::endl;

के बराबर है

std::cout << '\n' << std::flush;

इसलिए,

  • उपयोग करें std::endlयदि आप आउटपुट के लिए तत्काल फ्लश को बाध्य करना चाहते हैं।
  • उपयोग करें \nयदि आप प्रदर्शन के बारे में चिंतित हैं (यदि आप <<ऑपरेटर का उपयोग कर रहे हैं तो शायद ऐसा नहीं है )।

मैं \nज्यादातर लाइनों पर उपयोग करता हूं ।
फिर std::endlएक पैराग्राफ के अंत में उपयोग करें (लेकिन यह सिर्फ एक आदत है और आमतौर पर आवश्यक नहीं है)।

अन्य दावों के विपरीत, \nचरित्र लाइन अनुक्रम के सही प्लेटफ़ॉर्म अंत में मैप किया जाता है, अगर धारा एक फ़ाइल में जा रही है ( std::cinऔर std::coutविशेष लेकिन अभी भी फ़ाइलें (या फ़ाइल जैसी))।


5
कई मामलों में, "तुरंत आउटपुट देखें" एक लाल हेरिंग है, क्योंकि coutयह बंधा हुआ है cin, जिसका अर्थ है कि यदि आप इनपुट पढ़ते हैं cin, coutतो पहले फ्लश किया जाएगा। लेकिन अगर आप बिना पढ़े ही प्रोग्रेस बार या कुछ और दिखाना चाहते हैं cin, तो यकीन है, फ्लशिंग उपयोगी है।
क्रिस जस्टर-यंग

9
@ LokiAstari: यदि आप << संचालक का उपयोग कर रहे हैं, तो आप शायद प्रदर्शन के बारे में चिंतित नहीं हैं - क्यों? मुझे नहीं पता था कि operator<<प्रदर्शन नहीं है, या प्रदर्शन के लिए क्या विकल्प है? कृपया मुझे आगे समझने के लिए कुछ सामग्री की ओर इशारा करें।
लीजेंड्स 2

8
@ किंवदंतियां 2k: एक पुरानी पत्नियों की कहानी है कि सी ++ स्ट्रीम सी प्रिंटफ () के रूप में प्रदर्शन करने वाली नहीं हैं। हालांकि एक हद तक सच है कि गति का मुख्य अंतर गलत तरीके से C ++ स्ट्रीम का उपयोग करने वाले लोगों के कारण होता है। stackoverflow.com/a/1042121/14065 C ++ में सी-स्ट्रीम के साथ अनइंस्टॉल आईस्ट्रीम को याद रखें sync_with_stdio(false)और अपने आउटपुट को लगातार फ्लश न करें। जब यह करना हो तो लाइब्रेरी को काम करने दें। stackoverflow.com/a/1926432/14065
मार्टिन

6
@ लोकी: एक शहरी किंवदंती है sync_with_stdioजो iostreams को तेज गति से तेज करती है। यह नहीं है
बेन Voigt

2
@BenVoigt: मैं ऊपर मेरे शब्दों के साथ सावधान था (इसलिए मैं उनके साथ खुश हूं)। यह stdio के रूप में प्रदर्शन करने वाला नहीं है (क्योंकि यह अधिक करता है)। BUT बहुत सारे प्रदर्शन अंतर के बारे में लोगों को शिकायत करते हैं जो stdio के साथ सिंक के कारण होता है।
मार्टिन यॉर्क

40

प्रदर्शन की समस्याएं हो सकती हैं, std::endlआउटपुट स्ट्रीम के फ्लश को बल देता है।


1
और यह कोई अन्य प्रसंस्करण कर सकता है जिसे स्थानीय प्रणाली को इस काम को अच्छी तरह से करने की आवश्यकता है।
dmckee --- पूर्व-मध्यस्थ बिल्ली का बच्चा

30

यदि आप उपयोग करने जा रहे हैं तो वहां एक और फ़ंक्शन कॉल निहित है std::endl

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

a) कॉल ऑपरेटर <<एक बार।
b) कॉल ऑपरेटर को <<दो बार।


19
यह स्पष्ट हो सकता है, लेकिन इसका थ्रेडेड कार्यक्रमों पर बहुत अधिक प्रभाव पड़ता है, जहां, आम तौर पर, पहला संस्करण एक शॉट में एक एकल पंक्ति लिखेगा, जहां दूसरे संस्करण को अन्य थ्रेड्स से लिखकर विभाजित किया जा सकता है। अक्सर मैं खुद को std :: cout << "hello \ n" << std :: flush लिखने से बचता हूँ।
स्मार्प्स

किस बारे में std::cout << "Hello" << "\n";?
बक्सर

1
@byxor बफर के अलावा अन्य उत्तरों में वर्णित फ्लशिंग को छोड़कर लगभग समान है। वैसे भी, यह तब बेमानी है जब आप दो स्ट्रिंग शाब्दिक को एक में मिला सकते हैं।
iBug

खैर, अगर स्ट्रिंग मुद्रित करने के लिए नहीं एक शाब्दिक, तो करने के लिए कॉल है <<मामले में 2 होगा एक साथ ही, इस प्रकार मैं एक या दो के लिए की जरूरत का दावा नहीं होगा <<(सामान्य रूप में या दो फ़ंक्शन कॉल) एक हो \nऔर के बीच अंतर endl
एनरिको मारिया डे एंजेलिस

योग्य नहीं, यही कारण है कि मैं \ n का उपयोग नहीं करता हूं।
कार्लो वुड

28

मुझे मानक में इस बारे में पढ़ना याद था, इसलिए यहाँ जाता है:

C11 मानक देखें जो परिभाषित करता है कि मानक धाराएं कैसे व्यवहार करती हैं, क्योंकि C ++ प्रोग्राम CRT को इंटरफ़ेस करता है, C11 मानक को यहां फ्लशिंग नीति को नियंत्रित करना चाहिए।

आईएसओ / आईईसी 9899: 201x

7.21.3 §7

प्रोग्राम स्टार्टअप पर, तीन पाठ धाराएँ पूर्वनिर्धारित होती हैं और इन्हें स्पष्ट रूप से खोलने की आवश्यकता नहीं होती है - मानक इनपुट (पारंपरिक इनपुट पढ़ने के लिए), मानक आउटपुट (पारंपरिक आउटपुट लिखने के लिए), और मानक त्रुटि (डायग्नोस्टिक आउटपुट लिखने के लिए)। जैसा कि शुरू में खोला गया था, मानक त्रुटि स्ट्रीम पूरी तरह से बफर नहीं है; मानक इनपुट और मानक आउटपुट स्ट्रीम पूरी तरह से बफ़र किए जाते हैं यदि और केवल अगर स्ट्रीम को निर्धारित किया जा सकता है तो एक इंटरैक्टिव डिवाइस को संदर्भित नहीं करना चाहिए।

7.21.3 §3

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

इसका मतलब यह है कि std::coutऔर std::cinपूरी तरह से बफ़र्ड हैं यदि और केवल अगर वे एक गैर-इंटरैक्टिव डिवाइस का उल्लेख कर रहे हैं। दूसरे शब्दों में, यदि स्टडआउट एक टर्मिनल से जुड़ा हुआ है, तो व्यवहार में कोई अंतर नहीं है।

हालांकि, अगर std::cout.sync_with_stdio(false)कहा जाता है, तो '\n'इंटरेक्टिव उपकरणों के लिए भी एक फ्लश का कारण नहीं होगा। अन्यथा फाइलों के लिए पाइपिंग के '\n'बराबर है std::endl: c ++ ref on std :: endl


19

वे दोनों उचित अंत-पंक्ति चरित्र (ओं) को लिखेंगे। उस एंडल के अलावा बफर को प्रतिबद्ध करने का कारण होगा। आप आमतौर पर फ़ाइल I / O करते समय एंडल का उपयोग नहीं करना चाहते हैं क्योंकि अनावश्यक कमिट्स प्रदर्शन को प्रभावित कर सकते हैं।



10

यदि आप Qt और का उपयोग करते हैं endl, तो आप गलती से एक गलत का उपयोग करके समाप्त हो सकते हैं endlजो आपको बहुत आश्चर्यजनक परिणाम देता है। निम्नलिखित कोड स्निपेट देखें:

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>

// notice that there is no "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution!" << endl;
    // This prints something similar to: "Finished Execution!67006AB4"
    return qapp.exec();
}

ध्यान दें कि मैंने endlइसके बजाय std::endl(जो सही होगा) लिखा था और जाहिर तौर पर qtextstream.h (जो QtCore का हिस्सा है) endlमें परिभाषित एक फ़ंक्शन है ।

किसी भी संभावित नामस्थान मुद्दों "\n"को endlपूरी तरह से दरकिनार करने के बजाय उपयोग करना । यह भी एक अच्छा उदाहरण है कि प्रतीकों को वैश्विक नामस्थान (जैसे Qt डिफ़ॉल्ट रूप से क्यों करता है) में रखना एक बुरा विचार है।


31
Urgh! कौन बनना चाहेगा कभी using namespace std;?? :-)
स्टीव फ़ॉली

2
बुरा। टिप्पणी के लिए धन्यवाद, मुझे यकीन है कि अन्य लोग इसमें भाग लेंगे।
हेड गीक

@SteveFolly मैं करता हूं। क्यों नहीं?
21ol'z o qoq

@ okol aszǝɥʇqoq यह तब तक ठीक है जब तक आप हेडर फ़ाइलों में ऐसा नहीं करते हैं।
स्मरलिन

1
@ .olɐǝzǝɥʇqoq कृपया टालें using namespace std;। इसे बुरा व्यवहार माना जाता है। देखें क्यों "नाम स्थान std का उपयोग कर रहा है?" बुरा अभ्यास माना जाता है?
LF


2

std::endlजोड़तोड़ के बराबर है '\n'। लेकिन std::endlहमेशा धारा प्रवाहित करता है।

std::cout << "Test line" << std::endl; // with flush
std::cout << "Test line\n"; // no flush

1

यदि आप अपने लैपटॉप के अलावा किसी और चीज पर अपना प्रोग्राम चलाने का इरादा रखते हैं, तो कभी भी endlस्टेटमेंट का उपयोग न करें । खासकर यदि आप बहुत सारी छोटी लाइनें लिख रहे हैं या जैसा कि मैंने अक्सर एक फ़ाइल में एकल वर्ण देखा है। का उपयोग endlNFS जैसी नेटवर्क फाइल सिस्टम को मारने के लिए जाना जाता है।


क्या यह निस्तब्धता के कारण है? मैं देख सकता हूं कि यह कैसे संभव हो सकता है।
हेड गीक

@ अक्सर। मैंने इसे डिस्क IO के प्रदर्शन के लिए भी देखा है।
sbi

0

संदर्भ के साथ यह केवल I / O मैनिपुलेटर का आउटपुट है

std::endlआउटपुट अनुक्रम ओएस में एक नई लाइन वर्ण सम्मिलित करता है और इसे फ्लश करता है जैसे कि os.put(os.widen('\n'))इसके बाद कॉल करके os.flush()

कब इस्तेमाल करें:

इस मैनिपुलेटर का इस्तेमाल तुरंत आउटपुट की एक लाइन बनाने के लिए किया जा सकता है ,

जैसे

लंबे समय से चल रही प्रक्रिया से आउटपुट प्रदर्शित करते समय, कई थ्रेड्स की लॉगिंग गतिविधि या प्रोग्राम की लॉगिंग गतिविधि जो अप्रत्याशित रूप से क्रैश हो सकती है।

भी

Std :: cout का एक स्पष्ट फ्लश :: std :: system पर कॉल करने से पहले आवश्यक है, यदि स्पैन्ड प्रक्रिया किसी भी स्क्रीन I / O को निष्पादित करती है। सबसे सामान्य इंटरएक्टिव I / O परिदृश्यों में, std :: endl तब निरर्थक होता है, जब इसका उपयोग std :: cout के साथ किया जाता है क्योंकि std :: cin, आउटपुट से std :: cerr, या प्रोग्राम समाप्ति के किसी भी इनपुट को std :: cout के लिए एक कॉल मजबूर करता है। .flush ()। कुछ स्रोतों द्वारा प्रोत्साहित '\ n' के स्थान पर std :: endl का उपयोग, आउटपुट प्रदर्शन को काफी कम कर सकता है।

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