这个程序只是一个有趣的项目,我以为我会用C ++练习,所有这一切都是计算一次公路旅行的价格。
使用CODE :: BLOCKS对所有这些编码进行了类型化和编译,在启动程序时它完成没有错误,if语句的反应就好像无论我输入什么,使用函数列出的第一个if语句都是真的。我确信编码是正确的,但我觉得我可能会遗漏一些东西。
的main.cpp
#include <iostream>
#include "Answers.h"
using namespace std;
int main()
{
Answers roadTrip;
roadTrip.intro();
return 0;
}
Answers.h
#ifndef ANSWERS_H
#define ANSWERS_H
#include <iostream>
using namespace std;
class Answers
{
public:
Answers();
int intro();
void dataInput();
void doubleChecking();
void incDataInput();
void incDataMpg();
void incDataGasPrices();
void incDataDistance();
int goodbye();
int finalGoodbye();
int calculations();
int mpg;
float gasPrices;
int distance;
string answer;
string incValue;
protected:
private:
};
#endif // ANSWERS_H
Answers.cpp
#include "Answers.h"
#include <iostream>
using namespace std;
Answers::Answers(){
}
Answers::intro(){
cout << "Hello and welcome to the trip calculator, how may I be of service?" << endl;
cout << "As of now,I am only able to EXIT from this program, or calculate a simple road trip" << endl;
cout << "Which would you like to do, exit, or calculate?: ";
cin >> answer; cout << "\n" << endl;
if(answer=="Calculate"||"calculate"||"Road trip"||"road trip"){
dataInput();
}
if(answer=="Exit"||"exit"||"Escape"||"escape"||"Quit"||"quit"){
return 0;
}
}
void Answers::dataInput(){
cout << "How many miles to the gallon does your car get?: ";
cin >> mpg; cout << "\n";
cout << "What are the average gas prices along your trip?: ";
cin >> gasPrices; cout << "\n";
cout << "How far away in miles is your destination?: ";
cin >> distance; cout << "\n" << endl;
doubleChecking();
}
void Answers::doubleChecking(){
cout << "Alright, so if I'm not mistaken:" << endl;
cout << "Your car gets " << mpg << " miles per gallon" << endl;
cout << "The average price of gas along the trip is $" << gasPrices << endl;
cout << "And your destination is approximately " << distance << " miles away\n" << endl;
cout << "Is this information correct?: ";
cin >> answer; cout << "\n" << endl;
if(answer=="Yes"||"yes"||"Y"||"y"){
calculations();
}
if(answer=="No"||"no"||"N"||"n"){
incDataInput();
}
}
void Answers::incDataInput(){
cout << "Oh? Well that wont be a problem" << endl;
cout << "So what information was entered incorrectly?" << endl;
cout << "Was it MPG, gas prices, or distance?: ";
cin >> answer; cout << "\n" << endl;
if(answer=="MPG"||"mpg"||"Miles per gallon"||"miles per gallon"){
incDataMpg();
}
if(answer=="Gas"||"gas"||"Gas prices"||"gas prices"){
incDataGasPrices();
}
if(answer=="Distance"||"distance"){
incDataDistance();
}
}
void Answers::incDataMpg(){
cout << "So tell me again, how many miles to the gallon does your car get?: ";
cin >> mpg; cout << "\n";
cout << "Your car gets " << mpg << " miles per gallon, is that correct?: ";
cin >> answer; cout << "\n" << endl;
if(answer=="Yes"||"yes"||"Y"||"y"){
doubleChecking();
}
if(answer=="No"||"no"||"N"||"n"){
incDataMpg();
}
}
void Answers::incDataGasPrices(){
cout << "So tell me again, what's the average price of gas along your road trip?: ";
cin >> gasPrices; cout << "\n";
cout << "The average price of gas along the trip is $" << gasPrices << ", is that correct?: ";
cin >> answer; cout << "\n" << endl;
if(answer=="Yes"||"yes"||"Y"||"y"){
doubleChecking();
}
if(answer=="No"||"no"||"N"||"n"){
incDataGasPrices();
}
}
void Answers::incDataDistance(){
cout << "So tell me again, approximately how many miles away is your destination?: ";
cin >> distance; cout << "\n";
cout << "Your destination is approximately " << distance << " miles away, is that correct?: ";
cin >> answer; cout << "\n" << endl;
if(answer=="Yes"||"yes"||"Y"||"y"){
doubleChecking();
}
if(answer=="No"||"no"||"N"||"n"){
incDataDistance();
}
}
Answers::calculations(){
int extraMoney = distance*.05;
int total = (distance/mpg)*gasPrices;
cout << "So according to my calculations, in order for your car to travel the " << distance << " miles needed" << endl;
cout << "It'd be smart to have at least $" << total << "for your overall road trip, but if I were you, I'd consider" << endl;
cout << "making it $" << total+extraMoney << "Leaving you " << extraMoney << " extra dollars to spend on food an necessities for the trip" << endl;
cout << "I think it should cover " << distance << " miles"; cout << "\n" << endl;
goodbye();
}
Answers::goodbye(){
cout << "Well, hasn't this been fun? We should do it again sometime. I hope I was able to help you out" << endl;
cout << "That being said, would you like me exit this program?: ";
cin >> answer;
if("Yes"||"yes"||"Y"||"y"){
return 0;
}
if("No"||"no"||"N"||"n"){
finalGoodbye();
}
}
Answers::finalGoodbye(){
cout << "Listen, it's nice that you wanna keep me around and all, but literally all I can do is calculate road trips" << endl;
cout << "... and quit out of myself" << endl;
cout << "That being said, would you like me exit this program?: ";
cin >> answer;
if("Yes"||"yes"||"Y"||"y"){
return 0;
}
if("No"||"no"||"N"||"n"){
finalGoodbye();
}
}
任何帮助都会非常感激,我之前遇到过这个问题,但我还是不确定如何修复它。
答案 0 :(得分:2)
像something == somethingelse || somethingthird || ...
这样的表达式并不能完成您的想法,因为operator precedence您的比较对于编译器来说是这样的
(answer=="Calculate")||"calculate"||"Road trip"||"road trip"
换句话说,它将answer
与字符串"Calculate"
进行比较,并将逻辑或运算符的结果与文字字符串常量进行比较,文字字符串常量将是非空指针所以总是如此,这意味着比较总是是真的。
你需要这样做。
answer=="Calculate" || answer=="calculate" || answer=="Road trip" || answer=="road trip"
答案 1 :(得分:0)
必须如此 if(回答==“MPG”||回答==“mpg”||回答==“每加仑英里数”||回答==“每加仑英里数”)
以及所有其他ifs。否则,检查指向“mpg”的指针和所有其他字符串指针是否不等于0.因此条件总是被评估为真。
答案 2 :(得分:0)
answer=="Yes"||"yes"||"Y"||"y"
没有按照您的想法行事。基本上,它将始终返回true,因为在您的“或”子句中,您只需输入始终被认为是真的const char *
值。
为了使此逻辑正常工作,您必须将其替换为answer=="Yes"||answer=="yes"||answer=="Y"||answer=="y"
。更好的是,toupper(answer.c_str()[0])=='Y'
。这同样适用于您的其他字符串比较if
语句。
答案 3 :(得分:0)
如果语句的反应就好像第一个if语句列出了函数[sic;例如,这一个:
if(answer=="Calculate"||"calculate"||"Road trip"||"road trip"){
]无论我输入什么都是如此。我确信编码是正确的,但我觉得我可能会遗漏一些东西。
那是哪个?代码是否正确?
实际上,代码对于您想要的内容是不正确的。你似乎想要这个:
if(answer=="Calculate"||answer=="calculate"||answer=="Road trip"||answer=="road trip"){
你的原文询问answer=="Calculate"
是否为真(可能是也可能不是)或"calculate"
为真(总是如此)或其他两个条件也是真的。< / p>
答案 4 :(得分:0)
首先,尽管代码使用没有选项调用的g ++编译器进行编译,但它不能使用Visual C ++进行编译,并且当使用选项-f-no-ms-extensions
来禁用语言扩展时,它不会使用g ++进行编译(曾用于Microsoft代码:
[C:\my\forums\so\169] > doskey /macros g++=g++ -std=c++14 -pedantic-errors -Wall -Wextra -fexec-charset=cp1252 $* [C:\my\forums\so\169] > g++ main.cpp Answers.cpp -fno-ms-extensions Answers.cpp:12:16: error: ISO C++ forbids declaration of 'intro' with no type [-fpermissive] Answers::intro() { ^ Answers.cpp:137:23: error: ISO C++ forbids declaration of 'calculations' with no type [-fpermissive] Answers::calculations() { ^ Answers.cpp: In member function 'int Answers::calculations()': Answers.cpp:147:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ Answers.cpp: At global scope: Answers.cpp:149:18: error: ISO C++ forbids declaration of 'goodbye' with no type [-fpermissive] Answers::goodbye() { ^ Answers.cpp:163:23: error: ISO C++ forbids declaration of 'finalGoodbye' with no type [-fpermissive] Answers::finalGoodbye() { ^ Answers.cpp: In member function 'int Answers::intro()': Answers.cpp:26:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ [C:\my\forums\so\169] > _
上面的错误,从早期C使用所谓的“隐式int”语法很容易修复,我把它作为练习留给你。
此外,为了与其他编译器一起编译,您需要将Answers.h
中的include指令从<iostream>
更改为<string>
。
修复代码,以便删除所有错误和所有警告诊断,清除编译,仍然存在为什么会这样的问题。
if(answer=="Calculate"||"calculate"||"Road trip"||"road trip") {
dataInput();
}
...始终执行dataInput()
,无论answer
的值是什么。
嗯,C ++运算符旨在支持这样的表达式:
if( x1 != x2 || y1 != y2 ) // The points are different
因此!=
和==
之类的关系运算符会在布尔运算符之前进行评估,例如||
。即关系运算符实际上具有更高的优先级。您可以在任何地方找到C ++运算符的优先级表,包括at cppreference.com。
与Python不同,运算符链没有特殊规则,因此answer
检查代码被解释为
if( ((((answer=="Calculate") || "calculate") || "Road trip") || "road trip") ) {
dataInput();
}
这是编译因为一个简单的字符串文字在可能的任何上下文中衰减到指向第一个char
的指针,并且这可能是因为指针进一步衰减 - 一个隐式转换 - 到布尔false
和{ {1}}。
nullpointer产生true
,而任何其他指针产生false
。
由于文字的指针不是空指针,因此上述内容相当于
true
现在你可以看到它完全独立于if( ((((answer=="Calculate") || true) || true) || true) ) {
dataInput();
}
的价值。
意识到这是为了检查给定字符串是否在一组给定的字符串中,可以编写一个名为eg的函数。 answer
,并按照以下方式使用它:
contains
定义这样的功能很简单:
if( contains( answer, Strings{ "Calculate", "calculate", "Road trip", "road trip" } ) )
{
// Whatever.
}
要将此代码或类似代码放入头文件中,以便重复使用:
#include <string>
#include <unordered_set>
using namespace std;
using Strings = unordered_set<string>;
auto contains( string const& item, Strings const& set )
-> bool
{ return (set.count( item ) > 0); }
,而不是直接在全局命名空间中;和using namespace std;
。此外,为了大幅减少不同套接字符串的数量,请考虑对整个inline
字符串进行大写或小写,并且通常要检查字符串。例如,检查该集是否包含answer
,而不是检查"CALCULATE"
,"Calculate"
和其他可能的变体。
更直接的解决方法是直接表达每个预期的比较,如下所示:
"calculate"
但这很笨拙,冗长,而且不会扩展。