2015-06-24 14 views
5

Tôi không thể tìm ra lý do tại sao logic đơn giản này trong khi vòng lặp không hoạt động.Tại sao logic đơn giản này không hoạt động?

Về cơ bản chức năng thực hiện là gì, phải mất một đối số và sẽ kiểm tra trong vòng lặp while để xem liệu nó có phải là "có" hay "không" sau đó giữ vòng lặp.

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); 
     } 
} 

Nhưng mặc dù tôi nhập "có" hoặc "không", nó vẫn sẽ lặp.

+3

Thay đổi '||' thành '&&'. – Maroun

+0

tại sao && bây giờ tôi thực sự bối rối. trong khi không có hoặc không có sau đó giữ vòng lặp, nếu "có" hoặc "không", sau đó phá vỡ các vòng lặp – airsoftFreak

+0

tôi thêm lời giải thích như một câu trả lời vì nó không phù hợp với nhận xét. – Maroun

Trả lời

17

De Morgan's laws trạng thái đó:

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

Áp dụng luật này trên của bạn với điều kiện bạn:

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

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

Bây giờ, việc xem tại sao sai là dễ dàng hơn.

Nếu newAnswer là thứ không phải là "Có" hoặc "có", nó sẽ được đánh giá là đúng và đó không phải là điều bạn muốn.

Giải pháp sẽ thay đổi || thành &&.

+0

Logic của tôi là thực sự xấu, im xấu hổ của bản thân mình. Làm thế nào để tôi thực hành logic của tôi? – airsoftFreak

+2

Bạn không nên xấu hổ. Đó là mục đích của việc nghiêng người và luyện tập. Tiếp tục cố gắng và hỏi, đó là cách học duy nhất. Bạn đang đi đúng hướng! Tôi vẫn còn mắc sai lầm ngớ ngẩn ngay cả sau 5 năm lập trình. – Maroun

+0

"Làm cách nào để tôi thực hành logic của mình?" Bằng cách thực hành logic. Kinh nghiệm thực hiện công việc. Nếu nó có thể hữu ích, hãy nghĩ đến && như "và cùng một lúc ...". Bạn muốn rằng vòng lặp ngắt khi giá trị đã nhập là "cùng một lúc" khác với tất cả những gì bạn muốn nói. Đó là giống như nói "ít nhất" (ngược lại với "cùng một lúc") bằng (ngược lại với "khác nhau") –

6

Hãy nghĩ về điều đó. Tôi hỏi bạn một câu hỏi có hoặc không. Bạn nói với tôi "không".

Tôi đi xuống danh sách của tôi, và dừng lại như SOON khi tôi nhận được một tuyên bố đúng, bởi vì đó là những gì hợp lý HOẶC có nghĩa là.

newAnswer! = "Có" >> đúng. Làm xong. Tiếp tục lặp.

Tốt, bạn nói. Lần này, bạn trả lời "Có".

newAnswer! = "Có" >> false

newAnswer! = "Else else" >> true. Làm xong. Tiếp tục lặp.

Đây là một thuật ngữ. Không thể làm cho điều kiện OR đó sai. Bạn nên sử dụng AND.

Nói cách riêng của bạn, nó không phải là "trong khi không có hoặc không" nhưng "trong khi không vâng VÀ không no và không n VÀ không y ..."

1

Logic là như sau:

Nếu đầu vào chuỗi của bạn là một yes:

newAnswer != "yes" --> false 

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

Các logic or nhiều true s và một false là một true. Điều này có nghĩa là đối với đầu vào của đầu vào yes, vòng lặp sẽ tiếp tục. Nếu bạn thay đổi tất cả các or s đó thành and s, lôgic and hợp lý của một số true s và một false sẽ là false. Nếu đầu vào là đầu vào yes, vòng lặp sẽ không tiếp tục.

2

Ngoài sự đảo ngược rõ ràng giữa & & và || tất cả các câu trả lời nói về, hãy để tôi đi một chút nữa, để làm cho sai lầm khác hiển nhiên (không phải thực sự là một lỗi, nhưng một điểm yếu thiết kế): bạn hỏi "có hay không" chấp nhận bất cứ điều gì và nếu câu trả lời trông giống như "yes" bạn lối thoát. Bất cứ điều gì khác chơi như một không. Thậm chí "một tách cà phê".

Và đảo ngược tất cả logic có cùng một sai lầm: kiểm tra N, n, Không, không để quyết định không thoát nghĩa là thoát nếu "trà và bánh quy" được trả lời.

Ngoài ra, getAnswer mất trả lời và gọi chooseOptions (mà lần lượt sẽ nhận được một số đầu vào để cung cấp cho getAnswer): bạn không looping: bạn là recoursing. Và bạn đang làm một điều tương tự (nhận được câu trả lời từ một đầu vào) từ hai nơi khác nhau. Điều gì xảy ra nếu tôi muốn thay đổi std::cin bằng một số luồng khác? Mọi thứ sẽ thay đổi? Ở bao nhiêu địa điểm khác nhau?

Một logic tốt hơn nhiều nên buộc các câu trả lời cho phù hợp.

Trong chương trình chính của bạn, bạn nên làm hầu như cái gì đó như

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"); 
} 

Hoặc, ngắn gọn hơn,

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 
} 

Bây giờ, cho phép nhận được vào logic câu trả lời:

Bạn phải có được một dòng đầu vào (không chỉ một từ: một dòng, kể từ khi tôi có thể gõ "vâng, tôi muốn"), do đó cin>>string không chơi tốt: tốt hơn std::get_line. Nếu đó là "có" trả về true, nếu "không" trả về false và nếu bất cứ điều gì khác lặp lại việc đọc.

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; 
    } 
} 

Điều này khiến bạn chấp nhận các biến thể "có hoặc không" nổi tiếng, nhưng từ chối bất kỳ điều gì khác.

Đi thậm chí furtherly, chúng ta có thể cosider ý kiến ​​cho rằng cin/cout thể loại khác của suối, và có thể không có ai "gõ".

Để tránh đi vào một vòng lặp vô hạn, chúng ta có thể giới thiệu một giới hạn nỗ lực và ném một ngoại lệ nếu nó đạt được:

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"); 
} 

và để cho người gọi để cuối cùng bắt và thực hiện một số hành động khác, hoặc cuối cùng duyên dáng chấm dứt.

Hơn nữa, chúng tôi có thể tham số không chỉ là i/o và các câu hỏi, mà còn là câu trả lời, nhưng điều này đang đi quá xa.

Các vấn đề liên quan