2012-05-30 17 views
22

तो मैं उत्सुक हूं कि ऐसा क्यों होता है।सी ++ बूलियन मूल्यांकन

int main() 
{ 
    bool answer = true; 
    while(answer) 
    { 
     cout << "\nInput?\n"; 
     cin >> answer; 
    } 
return 0; 
} 

अपेक्षित व्यवहार: 0 - बाहर निकलता है कार्यक्रम, 1 - फिर से संकेत देता है, किसी भी गैर शून्य पूर्णांक 1 के अलावा अन्य - फिर

संकेत देता है

वास्तविक व्यवहार: 0 - जैसी उम्मीद थी, 1 - जैसी उम्मीद थी, किसी भी गैर शून्य पूर्णांक 1 के अलावा अन्य - अनंत लूप

http://www.learncpp.com/cpp-tutorial/26-boolean-values/

से

प्रोग्राम एक अनंत लूप में क्यों जाता है?

+8

+1 एक अच्छी तरह से पूछे जाने वाले प्रश्न के लिए +1।बूलियन एक लाल हेरिंग है; असली मुद्दा स्ट्रीम इनपुट कार्यों के तरीके से करना है। एक चीज को एक int के साथ आज़माएं, और उसके बाद एक अक्षर दर्ज करें और देखें कि क्या होता है ;-) – Cameron

+0

शायद मैं गलत हूं लेकिन जब आप इनपुट फॉर्म कमांड लाइन लेते हैं ... क्या यह एक स्ट्रिंग नहीं बनता है और इसलिए आप वास्तव में हैं स्ट्रिंग और बूलियन के बीच कनवर्ट करना? जो चीजों को पेंच कर सकता है .... –

+0

कैमरून एक अच्छा मुद्दा बनाता है: एक चरित्र को एक पूर्णांक में परिवर्तित किया जा सकता है। उदाहरण के लिए, 'ए' == 65', लेकिन वही बात होती है। – chris

उत्तर

23

वास्तव में, एक bool पढ़ने में प्रयुक्त किया operator>> अधिभार केवल 0 या 1 के रूप में मान्य इनपुट के एक मूल्य के लिए अनुमति देता है। ऑपरेटर अधिभार num_get वर्ग टेम्पलेट, जो इनपुट धारा से अगले संख्या पढ़ता को defers और फिर प्रकार कार्य करता है (सी ++ 11 §22.4.2.1/6):

  • के लिए मूल्य हैं संग्रहीत किया जाना 0 है false संग्रहित है।

  • यदि मान 1 है तो true संग्रहीत है।

  • अन्यथा true संग्रहीत किया जाता है और ios_base::failbiterr को सौंपा गया है।

(err यहां धारा जहाँ से आप पढ़ रहे हैं की त्रुटि स्थिति है;। इस मामले में cin नोट है कि वहाँ व्यवहार को निर्दिष्ट अतिरिक्त भाषा जब boolalpha जोड़तोड़ प्रयोग किया जाता है, जो करने के लिए अनुमति देता है बूलियन्स डाला जा और निकाले उनके नाम, true और false उपयोग करते हुए;। मैं संक्षिप्तता के लिए इन अन्य विवरण दर्ज नहीं हुए)

जब आप शून्य या एक, असफल राज्य धारा है, जो आगे निष्कर्षण का कारण बनता है पर सेट हो जाता है के अलावा अन्य एक मूल्य के इनपुट असफल होना। answertrue पर सेट है और हमेशा के लिए true रहता है, जो अनंत लूप का कारण बनता है।

यह निष्कर्ष निकालने के बाद कि आप निष्कर्षण सफल रहे हैं और क्या स्ट्रीम अभी भी एक अच्छी स्थिति में है, आपको प्रत्येक निष्कर्षण के बाद स्ट्रीम की स्थिति का परीक्षण करना होगा। उदाहरण के लिए, आप अपने लूप को फिर से लिख सकते हैं:

bool answer = true; 
while (std::cin && answer) 
{ 
    std::cout << "\nInput?\n"; 
    std::cin >> answer; 
} 
+0

+1: स्वीकार किए गए एक से अधिक बेहतर जवाब क्योंकि यह बताता है कि मानक इस व्यवहार को अनिवार्य करता है। –

+0

सहमत हुए :) बेहतर समझ देने के प्रति जवाब बदलने के लिए जवाब बदल गया। निश्चित रूप से इनपुट प्रमाणीकरण हमेशा महत्वपूर्ण क्यों है इसका एक उदाहरण :) –

15

क्योंकि operator>> इनपुट 0 या 1 नहीं होने पर विफल रहता है, और जब यह विफल हो जाता है, तो यह इनपुट का उपभोग नहीं करता है। तो लूप में अंक पढ़ने और फिर बार-बार इसे पढ़ने में शामिल होते हैं।

यह देखने के लिए इस तरह कोड को बदलने का प्रयास करें:

if (cin >> answer) { 
    cout << answer << endl; 
} else { 
    cerr << "oops" << endl; 
    break; 
} 
+4

हालांकि आप आम तौर पर 'cin >> उत्तर के बजाय' if (! (Cin >> answer)) लिखना चाहते हैं; अगर (cin.fail()) ' –

+0

बस इस कोशिश की और कार्यक्रम" सॉन्ग "की तरह है यदि आप बस कुछ टाइप करते हैं और वापसी पर हिट करते हैं। हालांकि, अगर आप इसे फिर से लिखते हैं, तो यह इनपुट का मूल्यांकन करने के लिए चला जाता है। क्यूं कर? –

+3

'if (cin.fail())' विरोधी पैटर्न को प्रचारित करने के लिए डाउनवॉटेड। ऑपरेशन के परिणाम का परीक्षण करें (जैसा कि @SteveJessop सुझाता है) स्ट्रीम स्थिति नहीं। –

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