我无法弄清楚为什么while循环中的这个简单逻辑不起作用。
基本上该函数的作用是,它接受一个参数并检查while循环以查看它是否为“yes”或“no”然后继续循环。
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);
}
}
但即使我输入“是”或“否”,它仍会循环播放。
答案 0 :(得分:17)
"not (A and B)" is the same as "(not A) or (not B)"
根据您的条件适用此法律:
newAnswer != "Yes" || newAnswer != "yes" || ...
⇔
!(newAnswer == "Yes" && newAnswer == "yes" && ...)
现在更容易理解为什么这是错误的。
如果newAnswer
不是“是”或“是”,它将被评估为真,而这不是你想要的。
解决方案是将||
更改为&&
。
答案 1 :(得分:6)
想一想。我问你一个是或否的问题。你告诉我&#34;不&#34;。
我走下我的名单,然后停下来,因为我得到了一个真实的陈述,因为那是什么逻辑或意味着什么。
newAnswer!=&#34;是&#34; &GT;&GT;真正。完成。继续循环。
很好,你说。这一次,你回答&#34;是&#34;。
newAnswer!=&#34;是&#34; &GT;&GT;假
newAnswer!=&#34;其他任何事情&#34; &GT;&GT;真正。完成。继续循环。
这是同义反复。它不可能使OR条件为假。你应该使用AND。
用你自己的话说,它不是&#34;而不是是或否&#34;但是&#34;虽然不是,但不是没有和不是n而不是y ...&#34;
答案 2 :(得分:2)
除了&amp;&amp;和和||所有的回答都谈到了,让我更进一步,使另一个谬误显而易见(不是真正的错误,而是设计上的弱点):你问&#34;是或否&#34;接受任何事情,如果答案看起来像是&#34;是&#34;你退出其他任何东西都像没有。甚至&#34;一杯咖啡&#34;。
反转所有逻辑具有相同的谬误:检查 N,n,否,否决定不退出意味着退出,如果&#34;茶和饼干&#34 ;得到回答。
此外,getAnswer
接听并致电chooseOptions
(后者将获得一些输入以提供给getAnswer
):您不会循环:你正在重新开始。而且你正在从两个不同的地方做同样的事情(从输入中得到答案)。如果我想用其他流更改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");
}
或者,更简洁,
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
}
现在,让我们进入答案逻辑:
你必须得到一行输入(不只是一个单词:一行,因为我可以输入&#34;是的,我想&#34;),所以cin>>string
不能很好地发挥作用:更好std::get_line
。如果它是&#34;是&#34;返回true,如果&#34; no&#34;返回false,如果还有其他重复读数。
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;
}
}
这使你接受众所周知的&#34;是或否&#34;变种,但拒绝任何其他。
更进一步说,我们可以提出cin / cout可以是其他类型的流的想法,并且可能没有人&#34;打字&#34;。
为避免进入无限循环,我们可以引入尝试限制并在达到时抛出异常:
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");
}
让调用者最终捕获并执行其他操作,或最终正常终止。
此外,我们不仅可以参与i / o和问题的参数化,还可以参考答案,但这已经太过分了。
答案 3 :(得分: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
输入的输入,循环将继续。
如果您将所有or
更改为and
s,则多个and
和一个true
的逻辑false
将为false
。如果输入是yes
输入,则循环将不会继续。