我正在尝试构建一个简单的单操作计算器,以便练习while
和for
循环等技术,并且我正在尝试学习并理解如何使用“菜单”控制台。
我有一个程序可以为你提供一个列表(来自map
的条目,我能够使用的功能但几乎不知道)你必须选择的操作。
如果输入无效输入(非整数或超出范围的整数),则会提示您输入有效答案。现在我希望程序获取条目(1-4)并使它们对应于操作。
你会在我的代码中看到每个操作都有自己的方法(我认为这是一个很好的方法,特别是在方法之间练习)。我想要的是main
采用operatorSelection
,并使用它来选择要跳转到的方法。然后,它会计算result
并将其返回main
。
我想我可以通过使用map
实现这一点,operatorSelection
对应map
中的条目,并使用该条目的相应字符串来调用方法(其中每个方法)与map
)中的名称相同。
在回答之前注意
我是新手,我想知道优化的方法。我希望它简单但有效;我不知道我正在使用的一些功能,尤其是map
。我已经简要阅读了vector
和array
,但我不知道如何使用它们。我意识到我的函数中的map
似乎按字母顺序打印,我希望能够完全根据自己的喜好对条目进行排序。有没有比用map
更好的方法来解决这个问题?
这是我的代码(操作方法不完整,我知道):
// OneOpCalc.cpp : Defines the entry pofloat for the console application.
#include "stdafx.h"
using namespace std;
int operatorSelection;
float firstNumber,secondNumber,result;
int main(float argc, char* argv[])
{
bool validInput = false;
map<string,int> Operations;
Operations.insert(pair<string, int>("Addition", 1));
Operations.insert(pair<string, int>("Division", 2));
Operations.insert(pair<string, int>("Multiplication", 3));
Operations.insert(pair<string, int>("Subtraction", 4));
cout << "Welcome to OneOpCalc. ";
while (!validInput)
{
cout << "Please select an operation by its number: ";
cin >> operatorSelection;
if (!cin || operatorSelection > 5 || operatorSelection < 1)
{
cout << "Error: Invalid entry. Try again." << endl << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
{
validInput = true;
}
}
system("pause");
return 0;
}
float Addition (float firstNumber, float secondNumber)
{
result=firstNumber+secondNumber;
return (result);
}
float Subtraction (float firstNumber, float secondNumber)
{
result=firstNumber-secondNumber;
return (result);
}
float Multiplication (float firstNumber, float secondNumber)
{
result=firstNumber*secondNumber;
return (result);
}
float Division (float firstNumber, float secondNumber)
{
result=firstNumber/secondNumber;
return (result);
}
简单地提出问题:
根据用户输入调用方法的好方法是什么?
答案 0 :(得分:1)
在您的特定情况下,最好使用指向函数的指针映射:
map<int,float (*)(float, float)> Operations;
Operations.insert(pair<int,float (*)(float, float)>(1, Addition));
Operations.insert(pair<int,float (*)(float, float)>(2, Division ));
Operations.insert(pair<int,float (*)(float, float)>(3, Multiplication));
Operations.insert(pair<int,float (*)(float, float)>(4, Subtraction));
这样你就可以简单地调用像
这样的函数Operations[operatorSelection](0,1);
P.S。你的代码中有一些拼写错误 - 应该是float result =而不是结果,也许是其他...
就效率而言,简单的switch()语句可能是最有效的......
答案 1 :(得分:1)
要回答您的问题:switch
是合适的(见下文)
其他可能性有:
一个带有 Ilya Kobelevskiy 的函数指针的map
,或者你使用enum
代替地图而不是地图,如果你需要所有这些(有一个看看enums)。但首先让我们来看看你的代码:
float
中使用argc
作为main
。参数计数是一个自然数,而不是浮点数(断裂)。不要忘记你的包括:
#include <iostream> // for cin / cout
#include <map> // for the map
#include <limits> // for numeric_limits<...>
您应该更好地使用system("pause")
,而不是std::cin.get()
。它具有相同的效果,但它是可移植的,并且仅在Windows下工作。
!cin
cin == null
,它与!cin.good()
基本相同
result
,是吗?实际上,你可以直接返回结果,而不必在以前保存它。以下是您编写代码的工作示例:
#include "stdafx.h" // inconvenient unportable windows stuff
#include <iostream> // cin and cout
#include <map> // the map
#include <limits> // numeric_limits
#include <string> // strings (obviously)
using namespace std;
int operatorSelection;
float firstNumber,secondNumber,result;
int main(int argc, char* argv[])
{
bool validInput = false;
map<string,int> Operations;
Operations.insert(pair<string, int>("Addition", 1));
Operations.insert(pair<string, int>("Division", 2));
Operations.insert(pair<string, int>("Multiplication", 3));
Operations.insert(pair<string, int>("Subtraction", 4));
cout << "Welcome to OneOpCalc. ";
while (!validInput)
{
cout << "Please select an operation by its number: ";
cin >> operatorSelection;
if (!cin.good() || operatorSelection > 4 || operatorSelection < 1)
{
cout << "Error: Invalid entry. Try again." << endl << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
{
validInput = true;
}
}
cin.get();
return 0;
}
float Addition (float firstNumber, float secondNumber)
{
return firstNumber+secondNumber;
}
float Subtraction (float firstNumber, float secondNumber)
{
return firstNumber-secondNumber;
}
float Multiplication (float firstNumber, float secondNumber)
{
return firstNumber*secondNumber;
}
float Division (float firstNumber, float secondNumber)
{
return firstNumber/secondNumber;
}
这是一个关于你的最终计划如何的建议。当然,还有很多事情你可以改进! (例如:使用类和OO代码)
#include "stdafx.h" // inconvenient unportable windows stuff
#include <iostream> // cin and cout
#include <map> // the map
#include <limits> // numeric_limits
#include <string> // strings (obviously)
#include <cmath> // for NaN. ATTENTION: for gcc you have to compile with -lm
using namespace std;
int main(int argc, char* argv[])
{
int operatorSelection;
float firstNumber, secondNumber, result;
cout << "Welcome to OneOpCalc. ";
while (true)
{
cout << "Please select an operation by its number: ";
cin >> operatorSelection;
if (!cin.good() || operatorSelection > 4 || operatorSelection < 1)
{
cout << "Error: Invalid entry. Try again." << endl << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
{
break;
}
}
do
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin >> firstNumber;
} while(!cin.good());
do
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin >> secondNumber;
} while(!cin.good());
switch(operatorSelection)
{
case 1:
result = firstNumber + secondNumber;
break;
case 2:
// don't devide by 0!
if(secondNumber == 0.0)
{
result = NAN;
}
else
{
result = firstNumber / secondNumber;
}
break;
case 3:
result = firstNumber * secondNumber;
break;
case 4:
result = firstNumber - secondNumber;
break;
default:
cout << "I'm sorry, something went terribly wrong";
return -1;
}
cout << "Your result is: " << result;
cin.ignore();
cin.get();
return 0;
}