0

我正在尝试构建一个简单的单操作计算器以练习whilefor循环之类的技术,并且我正在尝试学习和理解在控制台中拥有“菜单”的方法。

我有一个程序,它为您提供了一个map您必须从中选择的操作列表(来自 的条目,一个我能够使用但几乎一无所知的功能)。

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

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

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

在回答之前请注意
我是新手,我想知道解决这个问题的优化方法。我想要它简单但高效;我不知道我正在使用的一些功能,尤其是map. 我已经简要地阅读了vectorand array,但我不知道如何使用它们。我意识到map我的功能似乎按字母顺序打印,我希望能够完全按照自己的喜好对条目进行排序。有没有比 with 更好的方法来解决这个问题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);
}

简单地说:
根据用户输入调用方法的好方法是什么?

4

2 回答 2

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);

PS您的代码中几乎没有错别字-应该是浮动结果=而不是结果,也许是其他...

但就效率而言,一个简单的 switch() 语句可能是最有效的......

于 2013-08-08T22:06:03.227 回答
1

回答您的问题: aswitch是合适的(见下文)

其他可能性是:
AmapIlya Kobelevskiyenum提到的函数指针,或者如果您需要所有这些,则使用 an代替地图(查看enums)。但首先让我们看一下您的代码:

  • 你不应该floatargc你的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我认为不是这样的全局变量,是吗?您实际上可以直接返回结果,而无需将其保存在某个地方。
  • 全局变量有些不好的做法。尽量避免这些。

这是您的代码的一个工作示例,它也可以编译:

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

一般来说,我可以向你推荐这个链接,尤其是教程部分。此外,请随时 google 以获取更多教程并尝试示例。

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

于 2013-08-08T22:34:51.483 回答