C++ 为什么这个简单的逻辑没有';不行?
我就是不明白为什么while循环中的这个简单逻辑不起作用 该函数的基本功能是,它接受一个参数,并在while循环中检查它是否为“yes”或“no”,然后继续循环C++ 为什么这个简单的逻辑没有';不行?,c++,C++,我就是不明白为什么while循环中的这个简单逻辑不起作用 该函数的基本功能是,它接受一个参数,并在while循环中检查它是否为“yes”或“no”,然后继续循环 void getAnswer(string answer) { string newAnswer = ""; newAnswer = answer; while (newAnswer != "Yes" || newAnswer != "yes" || newAnswer != "Y" || newAnswer
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);
}
}
void getAnswer(字符串应答){
字符串newAnswer=“”;
新答案=答案;
while(newAnswer!=“Yes”| newAnswer!=“Yes”| newAnswer!=“Y”| newAnswer!=“Y”| newAnswer!=“No”| newAnswer!=“No”){
无法回答;
}
如果(newAnswer==“Yes”| | newAnswer==“Yes”| | newAnswer==“Y”| | newAnswer==“Y”){
选择选项();
}否则{
想一想。我问你一个是或不是的问题。你告诉我“不”
我沿着我的清单,一找到一个真实的陈述就停下来,因为这就是逻辑OR的意思
newAnswer!=“是”>>正确。完成。继续循环
很好,你说。这次,你回答“是”
新答案!=“是”>>错误
newAnswer!=“其他任何内容”>>正确。完成。继续循环
这是一个重言式。不可能使它或条件为假。你应该使用AND
用你自己的话来说,不是“whilenotyes或no”,而是“whilenotyes和notno,notn和noty…”陈述:
"not (A and B)" is the same as "(not A) or (not B)"
在您的情况下对您适用本法:
newAnswer != "Yes" || newAnswer != "yes" || ...
⇔
现在更容易看出它为什么错了
如果newAnswer
不是“Yes”或“Yes”,那么它将被评估为true,而这不是您想要的
解决方案是将|
更改为&
逻辑如下:
如果字符串输入为是
:
newAnswer != "yes" --> false
newAnswer != "Yes" --> true
newAnswer != "Y" --> true
newAnswer != "y" --> true
newAnswer != "No" --> true
newAnswer != "no" --> true
多个true
和一个false
的逻辑或为true
。这意味着对于yes
输入,循环将继续。
如果您将所有这些或更改为和s,那么几个真的和一个假的逻辑和将是假的
。如果输入是是的
输入,循环将不会继续。除了和之间明显的倒置之外,所有答案都是关于这一点的,让我再深入一点她,让另一个谬论变得明显(不是真正的错误,而是设计缺陷):你问“是或否”接受任何东西,如果答案看起来是“是”,你就退出。其他任何东西都像是“否”。甚至“一杯咖啡”
把所有逻辑颠倒过来也有同样的谬误:检查N,N,No,No来决定不退出意味着如果回答了“茶和饼干”就退出
另外,getAnswer
接受应答和呼叫选择选项
(这反过来将获得一些输入,以提供给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
}
现在,让我们进入答案逻辑:
您必须获得一行输入(而不仅仅是一个单词:一行,因为我可以键入“yes,I want”),因此cin>>字符串不能很好地播放:betterstd::get_line
。如果是“yes”,则返回true,如果是“no”,则返回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;
}
}
bool-getAnswer(标准::istream&istr,标准::ostream&ostr,
常量std::string和prompt,常量std::string和reprompt)
{
ostr将|
更改为&&
。为什么我现在真的很困惑。如果不是是或不是,那么继续循环,如果是或不是然后打破循环我添加了解释作为答案,因为它不适合评论。如果它是肯定的,它不是否定的,循环继续。a!=b | | a!=c
如果b
和c
不一样,则总是正确的,因为如果第一个是错误的(因此a==b
),第二个定义是正确的。我的逻辑真的很糟糕,我为自己感到羞耻。我该如何实践我的逻辑?你不应该感到羞耻。这就是学习和实践的目的。不断尝试和提问,这是唯一的学习方式。你走对了!即使在编程5年之后,我仍然在犯愚蠢的错误。“我如何实践我的逻辑?”通过实践逻辑。经验起作用。如果有帮助的话,想一想&&as“同时…”。当输入的值“同时”与您所指的值不同时,您希望循环中断。这与说“至少”(与“同时”相反)相等(与“同时”相反)是一样的不同”)@marounnaroun:“如果newAnswer不是“是”或“是”……那么……newAnswer可以是任何类型(包括“是”和“是”),并且&&链将始终为假,因为它不能同时等于不同的类型
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;
}
}
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");
}