过滤用户输入并使其对应菜单选项

时间:2013-08-08 18:54:52

标签: c++ methods map user-input calculator

我正在尝试构建一个简单的单操作计算器,以便练习whilefor循环等技术,并且我正在尝试学习并理解如何使用“菜单”控制台。

我有一个程序可以为你提供一个列表(来自map的条目,我能够使用的功能但几乎不知道)你必须选择的操作。

如果输入无效输入(非整数或超出范围的整数),则会提示您输入有效答案。现在我希望程序获取条目(1-4)并使它们对应于操作。

你会在我的代码中看到每个操作都有自己的方法(我认为这是一个很好的方法,特别是在方法之间练习)。我想要的是main采用operatorSelection,并使用它来选择要跳转到的方法。然后,它会计算result并将其返回main

我想我可以通过使用map实现这一点,operatorSelection对应map中的条目,并使用该条目的相应字符串来调用方法(其中每个方法)与map)中的名称相同。

在回答之前注意
我是新手,我想知道优化的方法。我希望它简单但有效;我不知道我正在使用的一些功能,尤其是map。我已经简要阅读了vectorarray,但我不知道如何使用它们。我意识到我的函数中的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);
}

简单地提出问题:
根据用户输入调用方法的好方法是什么?

2 个答案:

答案 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()基本相同
  • 如果您只有4个操作,请不要允许5作为输入(您当前允许)
  • 另外,在你的函数中,你正在改变我认为不是那种意图的全局变量result,是吗?实际上,你可以直接返回结果,而不必在以前保存它。
  • 全局变量有点bad practice。尽量避免这些。

以下是您编写代码的工作示例:

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

通常我可以向您推荐此link,尤其是tutorial部分。此外,请随时谷歌获取更多教程并试用示例。

另一个提示:如果您不想使用stdafx.h,请在项目属性中禁用预编译的标头。请查看thisthis