2015-06-24 14 views
5

मुझे यह पता नहीं लगा कि लूप काम नहीं करते समय यह सरल तर्क क्यों है।यह सरल तर्क क्यों काम नहीं करता है?

असल में फ़ंक्शन क्या करता है, यह तर्क लेता है और यह देखने के लिए थोड़ी देर में जांच करेगा कि यह "हाँ" या "नहीं" है, तो लूपिंग रखें।

void getAnswer(string answer) { 

    string newAnswer = ""; 
    newAnswer = answer; 
    while (newAnswer != "Yes" || newAnswer != "yes" || newAnswer != "Y" || newAnswer != "y" || newAnswer != "No" || newAnswer != "no") { 
      cout << "Enter yes or no.." << endl; 
      cin >> newAnswer; 

     } 

     if (newAnswer == "Yes" || newAnswer == "yes" || newAnswer == "Y" || newAnswer == "y") { 
      chooseOptions(); 
     } else { 
      cout << "Bye See you again " << endl; 
      exit(1); 
     } 
} 

लेकिन हालांकि मैं "हाँ" या "नहीं" दर्ज करता हूं, फिर भी यह लूपिंग करेगा।

+3

'' '' '' && 'बदलें। – Maroun

+0

क्यों और अब मैं वास्तव में उलझन में हूं। जबकि हां नहीं, नहीं, फिर लूपिंग रखें, अगर "हां" या "नहीं" तो लूप को तोड़ें – airsoftFreak

+0

मैंने स्पष्टीकरण को उत्तर के रूप में जोड़ा क्योंकि यह टिप्पणी में फिट नहीं है। – Maroun

उत्तर

17

De Morgan's laws कि:

"not (A and B)" is the same as "(not A) or (not B)" 

अपनी हालत पर अपने पर इस नियम को लागू करना:

newAnswer != "Yes" || newAnswer != "yes" || ... 

!(newAnswer == "Yes" && newAnswer == "yes" && ...) 

अब यह देखना आसान है कि यह गलत क्यों है।

यदि newAnswer ऐसा कुछ है जो "हां" या "हां" नहीं है, तो इसका मूल्यांकन सही होगा, और यह वही नहीं है जो आप चाहते हैं।

समाधान || से && बदल जाएगा।

+0

मेरे तर्क वास्तव में बुरा है, अपने आप पर शर्म im। मैं अपने तर्क का अभ्यास कैसे करूं? – airsoftFreak

+2

आपको शर्मिंदा नहीं होना चाहिए। यह झुकाव और अभ्यास का उद्देश्य है। कोशिश करते रहें और पूछें, यही सीखने का एकमात्र तरीका है। आप सही रास्ते पर हैं! मैं प्रोग्रामिंग के 5 साल बाद भी मूर्खतापूर्ण गलतियों को कर रहा हूं। – Maroun

+0

"मैं अपने तर्क का अभ्यास कैसे करूं?" तर्क का अभ्यास करके। अनुभव नौकरी करता है। अगर यह मदद कर सकता है, तो "और एक ही समय में ..." के रूप में सोचें। आप चाहते हैं कि लूप तोड़ता है जब दर्ज मूल्य "एक ही समय में" आपके द्वारा किए गए सभी से अलग होता है। यह "कम से कम" ("एक ही समय में" के विपरीत) के बराबर है ("अलग" के विपरीत) –

6

इसके बारे में सोचें। मैं आपको एक हां या कोई सवाल नहीं पूछता हूं। तुम मुझे बताओ "नहीं"।

मैं अपनी सूची नीचे जाता हूं, और जैसे ही मैं एक सच्चे कथन पर जाता हूं, वैसे ही रुक जाता है, क्योंकि यह तर्कसंगत या साधन है।

नया Answers! = "हाँ" >> सच। किया हुआ। लूपिंग जारी रखें।

ठीक है, आप कहते हैं। इस बार, आप "हां" का जवाब देते हैं।

newAnswer! = "हाँ" >> झूठी

newAnswer! = "कुछ और" >> सच। किया हुआ। लूपिंग जारी रखें।

यह एक ट्यूटोलॉजी है। उस स्थिति को गलत बनाना संभव नहीं है। आपको और उपयोग करना चाहिए।

अपने स्वयं के शब्दों में, यह नहीं है ", जबकि नहीं हाँ या ना" लेकिन "जबकि नहीं हाँ और नहीं और नहीं नहीं n और y नहीं ..."

1

तर्क इस प्रकार है:

यदि आपका स्ट्रिंग इनपुट एक yes है:

newAnswer != "yes" --> false 

newAnswer != "Yes" --> true 
newAnswer != "Y" --> true 
newAnswer != "y" --> true 
newAnswer != "No" --> true 
newAnswer != "no" --> true 

तार्किक or कई true रों की और एक false एक true है। इसका मतलब है कि yes इनपुट के इनपुट के लिए, लूप जारी रहेगा। आप and रों करने के लिए उन सभी or रों बदलते हैं, तो कई true रों की तार्किक and और एक falsefalse हो जाएगा। यदि इनपुट yes इनपुट है, तो लूप जारी नहीं रहेगा।

2

& & और || के बीच स्पष्ट विचलन के अलावा || सभी उत्तर बातों के बारे में बात करते हैं, मुझे थोड़ा और आगे जाने दो, एक और झुकाव स्पष्ट करने के लिए (वास्तव में एक बग नहीं, बल्कि एक डिजाइन कमजोरी): आप "हाँ या नहीं" कुछ भी स्वीकार करते हैं और यदि उत्तर आपको "हाँ" जैसा दिखता है बाहर जाएं। कुछ और नहीं जैसे ना। यहां तक ​​कि "एक कप कॉफी"।

और सभी तर्कों को बदलने में समान गिरावट है: एन, एन, नहीं, के लिए बाहर निकलने का निर्णय लेने का अर्थ है कि "चाय और बिस्कुट" का उत्तर दिया गया है।

इसके अलावा, getAnswer का जवाब लेता है और chooseOptions कॉल (जो बदले में कुछ इनपुट getAnswer को देने के लिए मिल जाएगा): यदि आप नहीं पाशन कर रहे हैं: आप recoursing हैं। और आप दो अलग-अलग स्थानों से एक ही चीज (इनपुट से जवाब प्राप्त कर रहे हैं) कर रहे हैं। अगर मैं std::cin को किसी अन्य स्ट्रीम के साथ बदलना चाहता हूं तो यह क्या होगा? सबकुछ बदलना है? कितने अलग स्थानों में?

एक बेहतर तर्क तर्क को सुसंगत होने के लिए मजबूर होना चाहिए।

अपने मुख्य कार्यक्रम आप

bool do_exit = false; 
while(!do_exit) 
{ 
    //All useful stuff and then ... 

    do_exit = getAnswer(std::cin, std::cout, 
     "Do you want to exit? [yes/no]", 
     "please answer yes or no"); 
} 

या, अधिक concisely की तरह सबसे अधिक संभावना कुछ करना चाहिए में,

for(bool do_exit=false, !do_exit, do_exit=getAnswer(
     "Do you want to exit? [yes/no]", 
      "please answer yes or no")) 
{ 
    //usefull stuff here 
} 

अब, की सुविधा देता है इस सवाल का जवाब तर्क में मिल:

आप करने के लिए है इनपुट की एक पंक्ति प्राप्त करें (केवल एक शब्द नहीं: एक पंक्ति, क्योंकि मैं "हाँ, मैं चाहता हूं" टाइप कर सकता हूं), इसलिए cin>>string अच्छी तरह से नहीं खेलता है: बेहतर std::get_line। यदि यह "हां" सच है, तो "नहीं" झूठी वापसी करता है और यदि कुछ और पढ़ने को दोहराता है।

bool getAnswer(std::istream& istr, std::ostream& ostr, 
    const std::string& prompt, const std::string& reprompt) 
{ 
    ostr << prompt << std::endl; 
    for(;;) 
    { 
    std::string line; 
    std::getline(istr,line); 
    if(line == "yes" || line == "Yes" || line == "Y" || line == "y") 
     return true; 
    if(line == "no" || line == "No" || line == "N" || line == "n") 
     return false; 
    ostr << reprompt << std::end; 
    } 
} 

यह आपको अच्छी तरह से जाना "हाँ या ना" वेरिएंट स्वीकार करते हैं, लेकिन कुछ और मना कर देता है।

आगे भी जाकर, हम इस विचार को समझ सकते हैं कि cin/cout अन्य प्रकार की धाराएं हो सकती है, और हो सकता है कि कोई भी "टाइपिंग" न हो।

अनंत लूप में जाने के लिए से बचने के लिए, हम एक प्रयास सीमा लागू कर सकते हैं और अगर यह तक पहुँच जाता है एक अपवाद फेंक:

bool getAnswer(std::istream& istr, std::ostream& ostr, 
    const std::string& prompt, const std::string& reprompt) 
{ 
    ostr << prompt << std::endl; 
    for(int attempt=5; attempt>0; --attempt) 
    { 
    std::string line; 
    std::getline(istr,line); 
    if(line == "yes" || line == "Yes" || line == "Y" || line == "y") 
     return true; 
    if(line == "no" || line == "No" || line == "N" || line == "n") 
     return false; 
    if(attempt>1) 
     ostr << reprompt << " ("<<attempt-1<<" attempts remaining)"<<std::endl; 
    } 
    throw std::domain_error("cannot get valid input"); 
} 

और फोन करने वाले अंत में पकड़ने के लिए जाने और कुछ अन्य कार्रवाई करते हैं, या अंत में कृपा से समाप्त करें।

इसके अलावा, हम केवल आई/ओ और प्रश्नों को ही नहीं, बल्कि उत्तर भी कर सकते हैं, लेकिन यह बहुत दूर हो रहा है।

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