2012-01-20 14 views
18

में अदालत और wcout मिश्रण मैं "सी ++ कुकबुक" जो निम्नलिखित स्निपेट था पढ़ रहा था:एक ही कार्यक्रम

// cout << s << std::endl; // You shouldn't be able to 
wcout << ws << std::endl;  // run these at the same time 

आप वास्तविक उदाहरण देखने में रुचि रखते हैं, तो यहां a link to the page on Google books है।

इसके अलावा, मुझे यह SO question मिला जो ऐसा लगता है कि wcout और cout मिश्रण ठीक है। क्या कोई मुझे बता सकता है कि यह टिप्पणी किस बारे में बात कर रही है?

संपादित

सी ++ स्टैंडर्ड से [27.4.1]:

इसी व्यापक और संकीर्ण चरित्र पर कार्रवाई मिश्रण धाराओं, फाइलों पर इस तरह के आपरेशनों मिश्रण के रूप में निर्दिष्ट के रूप में ही अर्थ विज्ञान इस प्रकार है आईएसओ सी मानक के संशोधन 1 में।

सी स्टैंडर्ड [7.19.2] से:

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

बाइट इनपुट/आउटपुट फ़ंक्शंस एक विस्तृत उन्मुख स्ट्रीम पर लागू नहीं होंगे और विस्तृत वर्ण इनपुट/आउटपुट फ़ंक्शंस बाइट-ओरिएंटेड स्ट्रीम पर लागू नहीं होंगे।

तो, मानक ऐसा लगता है कि आपको उन्हें मिश्रण नहीं करना चाहिए।

विजुअल C++ 10.0 fwide समारोह के लिए लागू नहीं किया गया जा रहा है के रूप में दर्ज है: हालांकि, मैं इस उद्धरण from this article पाया। और एक व्यावहारिक दृष्टिकोण से, कम से कम पूरी लाइनों को आउटपुट करने के स्तर पर यह स्पष्ट रूप से cout और wcout के उपयोग को जोड़ने के लिए ठीक काम करता है। तो, खुशी से, दृश्य सी ++ स्पष्ट रूप से मानक की आवश्यकताओं को नजरअंदाज करता है और एक अव्यवहारिक स्पष्ट सी फ़ाइल स्ट्रीम अभिविन्यास को बनाए रखता नहीं है।

और यह भी, जीसीसी के विषय में मैं here से इस उद्धरण पाया:

यह एक (नया) सुविधा, नहीं एक बग, देख libstdC++/11705 और सामान्य खोज में धारा उन्मुखीकरण के बारे में है सी मानक (सी 99, 7.1 9.2)। संक्षेप में आप बाइट उन्मुख और विस्तृत उन्मुख I/O मिश्रण नहीं कर सकते हैं। अभी के लिए, बग libstdC++/11705 में इंगित किया गया है, तो आप std :: ios :: sync_with_stdio (false) को कॉल करके अपने अपेक्षाओं के करीब कुछ प्राप्त कर सकते हैं; की शुरुआत में आपका प्रोग्राम।

उत्तर

16

जब cout या wcout पहली बार बुलाया जाता है, तो stdout के लिए अभिविन्यास सेट हो जाता है। cout के मामले में, stdout एक बाइट-ओरिएंटेड स्ट्रीम बन जाता है, और wcout के मामले में, stdout एक विस्तृत उन्मुख स्ट्रीम बन जाता है। सी ++ मानक [27.4.1] और सी मानक [7.1 9.2] के अनुसार, स्ट्रीम के अभिविन्यास को सेट करने के बाद, आपको उस फ़ंक्शन को कॉल नहीं करना चाहिए जो उस स्ट्रीम के अभिविन्यास के अनुकूल नहीं है।

2

मुझे कोई जानकारी नहीं है।

धागे को छोड़कर, आप किसी भी को दो वक्तव्य "एक ही समय में नहीं चला सकते"। आप निश्चित रूप से अपने कार्यक्रम के विभिन्न बिंदुओं पर cout और wcout का उपयोग कर सकते हैं। वे दोनों STDOUT पर नक्शा रखते हैं और यह वह है ... हालांकि आप कुछ मामलों में अलग-अलग बफरों का सामना कर सकते हैं और थोड़ा अप्रत्याशित आदेश प्राप्त कर सकते हैं।

जाहिर है, प्रत्येक "गंतव्य" धारा STDOUT पर एक उन्मुखीकरण imbues, और यह एक धारा है कि एक ओरिएंटेशन [C++11: 27.4.1] और [C99: 7.19.2] के साथ imbued किया गया है पर कार्रवाई मिश्रण करने की अनुमति नहीं है।

+0

मैंने वास्तव में पुस्तक के इरेटा पेज की जांच की क्योंकि मैंने सोचा कि यह एक गलती हो सकती है, लेकिन कुछ भी नहीं मिला। –

+0

@ जेसे: लेखक से संपर्क करने का समय, शायद। –

+0

क्या आप समझ सकते हैं कि आपका क्या मतलब है और वास्तव में क्या होता है: "वे दोनों STDOUT को मानचित्र करते हैं"? , धन्यवाद –

1

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

+0

क्या 'imbue' मानक में धाराओं के लिए परिभाषित नहीं है या मुझे इसकी व्याख्या कैसे करनी चाहिए? – Voo

+1

@Voo 'imbue()' वास्तव में ** ** सभी स्ट्रीम ऑब्जेक्ट्स के लिए परिभाषित किया गया है। हालांकि, 'std :: codecvt <...> 'का उपयोग करने के लिए आवश्यक एकमात्र स्ट्रीम बफर' std :: basic_filebuf <...>' है। हालांकि, इस तरह के स्ट्रीम बफर का उपयोग करने के लिए मानक स्ट्रीम ऑब्जेक्ट्स की आवश्यकता नहीं है। वे 'std :: basic_filebuf <...>' का उपयोग कर सकते हैं, लेकिन मैं इस पर भरोसा नहीं करता, आंशिक रूप से क्योंकि मैं कल्पना नहीं कर सकता कि मैं इसे इस तरह कार्यान्वित करूंगा।असल में, मुझे इसके लिए सी ++ 2011 मानक की जांच करनी चाहिए: यह निश्चित रूप से सी ++ 2003 में सच था लेकिन मुझे नहीं लगता कि यह बदल गया है। –

+0

यह दिलचस्प है - मैंने कभी भी उन फ़ाइलों के लिए 'imbue' का उपयोग किया जहां यह ठीक काम करता था, लेकिन मुझे उम्मीद है कि यह मानक स्ट्रीम ऑब्जेक्ट्स के लिए भी काम करेगा। जानना अच्छा है - लेकिन फिर एक कारण है कि मुझे इसे पहली बार मानक धाराओं के लिए कभी भी जरूरी नहीं था, इसलिए शायद यह अभ्यास में कोई बड़ा सौदा नहीं है .. – Voo

1

मानक से "नहीं" का उल्लंघन करना आमतौर पर अपरिभाषित व्यवहार के दायरे में पड़ता है। अपरिभाषित व्यवहार कुछ कार्यान्वयन पर ठीक से काम कर सकता है।

0

अनुमान के रूप में: cout और wcout दो अलग-अलग धाराएं हैं, और आपके द्वारा प्रदान किए गए उद्धरण इस बात के बारे में कुछ भी नहीं कहते हैं कि धारा अभिविन्यास अंतर्निहित फ़ाइल के अभिविन्यास से कैसे संबंधित है। हो सकता है कि हुड के नीचे धाराएं stdout चुपचाप पुन: पेश करें?

संबंधित मुद्दे