2012-11-16 40 views
9

std :: ws manipulator का उपयोग कर स्ट्रीम से निकालने के लिए कभी भी असफल बिट बढ़ाएं? निम्नलिखित कोड में, क्लैंग-संकलित (एक्सकोड 4.5.1 के भीतर) प्रोग्राम अंतिम दावे में विफल रहता है। ईओएफ पर स्पष्ट रूप से s >> std::ws असफल हो जाता है। फिर भी जीसीसी 4.7.2 दावा पारित करता है। क्या सही है?क्या std :: ws फ़ाइल के अंत में विफलता बढ़ाएं?

#include <iostream> 
#include <sstream> 
#include <cassert> 

int main(int argc, const char * argv[]) 
{ 
    { 
     // Read string with trailing ws. 
     std::istringstream s("test "); 
     std::string test; 

     s >> std::ws; 
     assert(!s.fail()); // No ws to skip, but no failure. 

     s >> test; 
     assert(test == "test"); 
     assert(!s.fail()); 

     s >> std::ws; 
     assert(!s.fail()); // No prob skipping trailing ws. 
    } 
    { 
     // Retry with no trailing ws. 
     std::istringstream s("test"); 
     std::string test; 

     s >> std::ws; 
     assert(!s.fail()); // No ws to skip, but no failure. 

     s >> test; 
     assert(test == "test"); 
     assert(!s.fail()); 

     s >> std::ws; 
     assert(!s.fail()); // CLANG: Skipping absent ws at eof raises failbit. 
    } 

    return 0; 
} 
+0

मेरे लिए जीसीसी 4.6, जीसीसी 4.7 और क्लैंग 3.1 सभी प्रत्येक assert – sehe

उत्तर

3

सी ++ 11, §27.7.2.4/1:

तो ws बंद हो जाता है वर्ण निकालने वहाँ कोई और अधिक उपलब्ध यह सेट eofbit, लेकिन नहीं failbit रहे हैं, क्योंकि।

तो, ws मैनिपुलेटर सीधे failbit सेट नहीं करता है। हालांकि, जैसा कि मार्शल क्लॉ अपने जवाब में बताता है, इसे करने की आवश्यकता नहीं है - इसे एक ऑब्जेक्ट ऑब्जेक्ट बनाना आवश्यक है, और अगर !stream.good() पर असफलता सेट करने के लिए संविदा ऑब्जेक्ट की आवश्यकता होती है।

+0

पास करते हैं तो क्या यह libC++ में एक बग है? – Matthias

+0

यह उत्तर C++ विनिर्देशों के अनुसार गलत है क्योंकि C++ 11 (मैंने C++ 03 spec की जांच नहीं की है)। –

+0

@ हावर्ड हिन्नेंट: यूप - मार्शल को वास्तव में "स्वीकृत" झंडा मिलना चाहिए, लेकिन केवल ओपी उत्तर को स्वीकार नहीं कर सकता है, और जब तक वह नहीं करता, मैं इसे हटा नहीं सकता। –

4

मेरा मानना ​​है कि libC++ मानक को सही ढंग से कार्यान्वित कर रहा है।

[मैं एन 32 9 0 से उद्धरण दे रहा हूं, जो ड्राफ्ट सी ++ 11 मानक है। सी ++ 14 इसे बदलता नहीं है। ]

ws [istream.manip] में वर्णित है, जिसमें कहा गया है:

प्रभाव:, एक अस्वरूपित इनपुट समारोह ( 27.7.2.3 में वर्णित है, पैरा 1) के रूप में व्यवहार कि यह नहीं है सिवाय वर्णों की संख्या की गणना करें और द्वारा दिए गए मान को is.gcount() पर आने वाली मान को प्रभावित नहीं करता है। एक संविदा ऑब्जेक्ट बनाने के बाद जब तक कि अगले उपलब्ध वर्ण सी व्हाइटस्पेस या अनुक्रम में कोई और वर्ण न हो, तब तक अक्षरों को निष्कर्ष निकाला जाए। व्हाइटस्पेस वर्णों को के रूप में उसी मानदंड के साथ प्रतिष्ठित किया जाता है जो सेंड्री :: सेंड्री (27.7.2.1.3) द्वारा उपयोग किया जाता है। यदि ws अक्षर निकालने से रोकता है क्योंकि वहां कोई और उपलब्ध नहीं है तो यह eofbit सेट करता है, लेकिन असफल नहीं होता है।

सही व्यवहार निर्धारित करने के लिए यहां मुख्य वाक्यांश "एक वस्तु ऑब्जेक्ट बनाने के बाद" है।

संतरी वस्तुओं [IStream :: संतरी] में वर्णित हैं, और पाठ वहाँ शुरू होता है ...

1 वर्ग संतरी एक वर्ग है कि अपवाद सुरक्षित उपसर्ग और प्रत्यय संचालन कर रही है के लिए जिम्मेदार है परिभाषित करता है।

स्पष्ट संत्री (basic_istream & है, bool noskipws = false);

2 प्रभाव: यदि is.good() गलत है, तो कॉल है .सेटस्टेट (विफलता)। अन्यथा, स्वरूपित या> अनफॉर्मेटेड इनपुट के लिए तैयार करता है। ... और इतने पर ...

, केवल संतरी निर्माता है कि उपलब्ध है कि इतना है कि एक ही है कि libC++ का उपयोग करता है है।

तो असफल बिट किसी भी अक्षर को निकालने से पहले सेट हो जाता है, इसलिए पैराग्राफ के अंत में पाठ लागू नहीं होता है।अगर धारा " " (यानी, अंत में एक ही स्थान) है, तो std::ws पर कॉल करने से असफल बिट सेट नहीं होता है, केवल eof (जो ओपी होने की उम्मीद है)।

+0

यह मेरे लिए मानक के उचित पढ़ने जैसा प्रतीत होता है, लेकिन चूंकि यह कम उपयोगी संस्करण 'std :: ws' की ओर जाता है, मुझे लगता है कि हमें जीसीसी की व्याख्या को सही के रूप में मानना ​​चाहिए। क्लैंग के संस्करण के साथ समस्या यह है कि इसे इनपुट के अंत में वैकल्पिक सफेद स्थान खाने के लिए उपयोग नहीं किया जा सकता है। –

+0

यदि हमें कार्यान्वयन के बीच विचलन मिला है, तो मुझे लगता है कि सी ++ मानकों समिति को यह तय करना चाहिए कि वे किस व्यवहार को निर्दिष्ट करना चाहते हैं, और मानक के उस खंड को फिर से शब्द दें ताकि यह स्पष्ट हो :-) –

+1

एलडब्लूजी बनाने के लिए दिशा-निर्देश मुद्दा: http://cplusplus.github.io/LWG/lwg-active.html#submit_issue –