C ++基本菜单驱动程序(调用函数)

时间:2014-02-10 00:42:10

标签: c++

我是编程的新手,正在试图弄清楚为什么会这样。

基本上我被要求设计一个菜单驱动的程序,它可以进行一些基本的存款/取款计算。我应该为每个进程编写不同的函数,并在必要时调用它们。

我遇到两个问题: 1)我的函数不是在程序中更新我的变量。例如它会运行,我可以输入我的起始余额,我可以输入我的交易类型和金额,但每次我从存款切换到写支票时,它会将余额重置为原始用户输入。

2)当我希望程序退出时,它仍然要求我输入双输入。不知道如何让它只接受“E”而不是“E号”

提前致谢。

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

//Prototypes for my functions that will be called in
void displayMenu();
double checkProcess(double, double);
double depositProcess(double, double);
double totalServCharge(double);

int main()
{
        //Variables needed for the problem
        char choice; //menu choice
    double transAmt, balance, numbServCharge; //transaction amount, current balance, total service charges, number of service charges

    numbServCharge = 0; //Start the counter for number of service charges at zero
    cout << "Checkbook Program\n\n";
    cout << "Enter the beginning balance:  "; 
    cin >> balance; //get the initial balance
    cout << endl;

    do
    {
        //Call the display menu function
        displayMenu();

        //Get user's choice and transaction amount from menu
        cout << "Enter a transaction:  ";
        cin >> choice >> transAmt;
        choice = toupper(choice);
        cout << endl;

        //Create an error message for invalid choice and get a second choice
        while((choice != 'C') && (choice != 'D') && (choice != 'E'))
        {
        cout << "Invalid selection.  Please choose C, D or E: ";
        cin >> choice;
        }

        //Set up for option #1 -- using a check
        if(choice=='C')
        {
        //Call check function and service charges function
        checkProcess(transAmt, balance);
        totalServCharge(numbServCharge);
        }

        //Set up for option #2 -- deposits
        if(choice=='D')
        {
        //Call deposit function and service charges function
        depositProcess(transAmt, balance);
        totalServCharge(numbServCharge);
        }

    }while(choice != 'E'); //Close program if option 3 is selected

    //Display final balance
    cout << "Processing end of the month";
    cout << "\nFinal balance :  $  " << fixed << setprecision(2) << balance << endl << endl;

    system("pause"); //Pause screen so it doesn't close right away
    return 0;
}

void displayMenu()
{
//Highlight menu options
cout << "\nCommands\n";
cout << "C amount - process a check in a specific amount\n";
cout << "D amount - process a deposit in a specific amount\n";
cout << "E - end the program\n\n";
}

double checkProcess(double transAmt, double balance)
{
cout << "\nProcessing check for $" << fixed << setprecision(2) << transAmt;
transAmt = transAmt + .25; //Add the service charge onto the transaction
balance = balance - transAmt; //Update account balence
cout << "\nBalance:  $" << fixed << setprecision(2) << balance;
cout << "\nService charge:  $0.25 for a check\n";
return balance;
}

double depositProcess(double transAmt, double balance)
{
cout << "\nProcessing Deposit for $" << fixed << setprecision(2) << transAmt << endl;
transAmt = transAmt - 0.25; //Add the service charge onto the deposit
balance = balance + transAmt; //Update account balence
cout << "Balance:  $" << fixed << setprecision(2) << balance << endl;
return balance;
}

double totalServCharge(double numbServCharge)
{
double totalServCharge = 0;
numbServCharge++; //Add one to the number of service charges there have been
totalServCharge = .25 * numbServCharge; //Update total cost of service charges
cout << "Total service charges:  $" << fixed << setprecision(2) << totalServCharge << endl; //Tell user total service charges so far
return numbServCharge;
}

3 个答案:

答案 0 :(得分:1)

当您使用参数调用函数时,在C ++中,您只能对这些参数的COPIES进行操作。如果要更改原始值,请将变量作为参考传递。

请参阅以下简单示例:

#include <iostream>

using namespace std;

void normal(int a)
{
    a += 10;
}

void by_reference(int &a) //Notice ampersand
{
    a += 10;
}

int by_return(int a)
{
    return a + 10;
}

int main()
{
    int a = 5;

    cout << "Start:     " << a <<endl;
    normal(a);
    cout << "Normal:    " << a <<endl;
    by_reference(a);
    cout << "Reference: " << a <<endl;
    a = by_return(a);
    cout << "Return:    " << a <<endl;
}

现在您可以看到,如果您将变量作为参考传递,它将被更改。

即使只是把&amp;在参数名称修复问题之前,我建议您使用return,它通常更简单,使您的代码看起来更好(更容易理解)。

另外,请更正缩进。当你处理更大的项目时,这非常重要。

希望这会有所帮助。 :)

答案 1 :(得分:1)

(1)您的变量没有更新,因为您没有更改它们;您正在更改传递给子例程的副本。您需要通过引用传递当前余额(以便在子例程范围中更改它时,您还要更改原始值)或将子例程的返回值分配给当前余额。

当您按值传递变量时(就像您现在一样),程序会复制该变量以在函数范围内使用。离开该范围时,将删除该副本。当您想要确保子例程不会改变调用它的范围内的任何内容时,请执行此操作。如果希望子例程更改传递给它的变量,请通过引用传递变量。在此函数签名中,“transAmt”按值传递,“balance”通过引用传递:

double foo(double transAmt, double& balance);

顺便提一下,如果您通过参考传递余额,则没有理由退回。无论如何,你现在没有对返回的值做任何事情。

(2)如果您想在给出“E”时不要求数字,请为“C”和“D”的条件块中的数字单独制作“cin”语句。现在所有输入代码都在所有情况下共享。如果你安排一些事情会让你在要求号码之前退出循环会更好。这样,你只需要写一次“cin”语句。

答案 2 :(得分:0)

1 |出现第一个问题是因为您实际上并未修改用户的输入。您正在传递变量,但是一旦返回新值,您就不会存储它,因此在主函数中忘记了该值。不是最好的解决方案,但它可能适合你这样做:

    if (choice == 'D')
    {
        //Call deposit function and service charges function
        balance = depositProcess(transAmt, balance); // Overwrite balance
        numbServCharge = totalServCharge(numbServCharge); // Overwrite numbServCharge
    }

或者以更有效的方式,您可以通过引用传递变量。您需要做的就是更改函数原型。

void totalServCharge(double&);
void depositProcess(double&, double&);

现在传入变量时,它将被函数直接修改。另请注意,函数数据类型已更改为void,因为您不再需要从函数返回值。

2 |您的第二个问题是您处理用户输入的方式。如果您想要求多个输入,有时可能最好使用单独的cout和cin语句。 在程序中设置的方式是让用户一次输入两个输入,因此如果您只输入E,它会耐心地等待下一次输入(transAmt)。最好处理所需的操作,然后输入金额。

非常一般的例子:

do {
    cout << "1 : Transaction or 2 : Exit" << endl;
    cin >> choice;
    if (choice == 2)
        break;

    cout << "1. Deposit\n" << "2. Check" << endl;
    cout << "Enter transaction type followed by amount" << endl;
    cin >> transType >> amount;
    // Then do what was specified in choice
} while (true); // Or whatever condition pleases you