简单的选择功能似乎不起作用(C ++)

时间:2013-08-17 02:00:47

标签: c++ command-line-interface fstream

我一直在我的c ++编程书中练习,它基本上要求我创建一个程序,它将获取3个文件,一个旧的主客户端数据文件(帐户,名称,余额),一个事务文件(帐户名称和信用或借记),然后是合并此文件并输出客户数据的新主文件的功能。我很确定我知道如何做到这一点,或者即使我不知道我能弄明白,我遇到的问题是一个简单的选择选择界面,其实现与另一个工作方式完全相同精细。当我第一次运行程序时,它将让我输入一个选项(int),然后运行相应的函数(我只有1个完全实现,即createMasterFile函数。在文件中创建条目并将它们读回屏幕只是用于调试和验证目的,它将返回到下面的while语句但是如果我在main函数和enterChoice()函数中观察选择函数,当我进行第一次选择(工作的那个)时那些变量(根据gdb)在AFM创建运行之前不要接受任何值,在此之前它表明它不在范围内,在它运行之后,一旦选择将采用原始值1,因为它命中,然后似乎跳过条件while语句,然后命中switch语句,它以某种方式将选项更改为0然后命中默认情况然后返回到while语句并且选择值为32767并再次似乎跳过condi while语句的部分内容在此时陷入无限循环,选择永远不会改变。在一个非常相似的程序(唯一的区别是工作的程序使用二进制文件而不是顺序文件)这很好。界面如下所示:

enum Choices {CREATE_MASTER =1, CREATE_TRANSACTION, SORT_MASTER, UPDATE_MASTER, SORT_TRANS, UPDATE_TRANS, MERGE, END  };

int choice;

while ( ( choice = enterChoice()) != END )
{
    switch( choice )
    {
        case CREATE_MASTER:
            createMasterFile( inOutOldMasterFile );
            break;
        case CREATE_TRANSACTION:
            break;
        case SORT_MASTER:
            break;
        case UPDATE_MASTER:
            break;
        case SORT_TRANS:
            break;
        case UPDATE_TRANS:
            break;
        case MERGE:
            break;
        default:
            cerr << "Incorrect choice" << endl;
            break;
    }
}

和enterchoice()函数是:

int enterChoice()
{
cout << "\nEnter your choice below" << endl
    << "1 - Create Master Record" << endl
    << "2 - Create Transaction Record" << endl
    << "3 - Sort Master File In Descending Order" << endl
    << "4 - Update Master File" << endl
    << "5 - Sort Transaction File" << endl
    << "6 - Update Transaction File" << endl
    << "7 - Merge Transaction and Old Master File" << endl
    << "8 - End Program\n?";

    int choice;
    cin >> choice;
    return choice;
}

如果您需要查看所有代码(仅为了清晰起见),那么(对于当前正在使用的函数)

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

void outputLine( int, const string, double );
void createMasterFile( fstream & );
int numberOfAccounts = 0;
void swap(int * const, int * const);
void swap( string * const, string * const);
void swap( double * const, double * const);
bool descending( int, int);
void sortAccounts(int, fstream &, bool (*)(int, int));
int enterChoice();

int main()
{
// create a fstream object for input and output to be passed to
// the functions that need to manipulate it.
fstream inOutOldMasterFile( "oldmaster.dat", ios::in | ios::out );
fstream inOutTransaction( "trans.dat", ios::in | ios::out );
ofstream outNewMaster( "newmaster.dat", ios::out);

enum Choices {CREATE_MASTER =1, CREATE_TRANSACTION, SORT_MASTER, UPDATE_MASTER, SORT_TRANS, UPDATE_TRANS, MERGE, END  };

int choice;

while ( ( choice = enterChoice()) != END )
{
    switch( choice )
    {
        case CREATE_MASTER:
            createMasterFile( inOutOldMasterFile );
            break;
        case CREATE_TRANSACTION:
            break;
        case SORT_MASTER:
            break;
        case UPDATE_MASTER:
            break;
        case SORT_TRANS:
            break;
        case UPDATE_TRANS:
            break;
        case MERGE:
            break;
        default:
            cerr << "Incorrect choice" << endl;
            break;
    }
}
return 0;
}

int enterChoice()
{
cout << "\nEnter your choice below" << endl
    << "1 - Create Master Record" << endl
    << "2 - Create Transaction Record" << endl
    << "3 - Sort Master File In Descending Order" << endl
    << "4 - Update Master File" << endl
    << "5 - Sort Transaction File" << endl
    << "6 - Update Transaction File" << endl
    << "7 - Merge Transaction and Old Master File" << endl
    << "8 - End Program\n?";

    int choice;
    cin >> choice;
    return choice;
}

void createMasterFile( fstream &clientFile )
{
if(!clientFile)
{
    clientFile.open("oldmaster.dat", ios::in | ios::out);
}

cout << "Enter the account, name and balance." << endl
    << "Enter end-of-file to end input (^d)\n? ";

int account;
string name;
double balance;

clientFile.seekp( 0, ios::beg );

// read account, name and balance from cin then place in file
while (cin >> account >> name >> balance )
{
    numberOfAccounts++;
    clientFile << account << ' ' << name << ' ' << balance << endl;

    cout << "?";
} //end while

clientFile.seekg( 0, ios::beg );

cout << left << setw(10) << "Account" << setw(13)
    << "Name" << "Balance" << endl << fixed << showpoint;

while( clientFile >> account >> name >> balance)
{
    outputLine( account, name, balance );
}

clientFile.close();
}

如果这是非常明显的,我很抱歉,但我已经尝试在近2天内找到一些答案,现在正在网上搜索。

提前致谢。

-Bobby

1 个答案:

答案 0 :(得分:1)

您的createMasterFile()似乎从std::cin读取,直到std::cin进入失败模式,例如,因为遇到错误的值或std::cin到达终点。此功能在读取后正确检查输入。

之后,在没有先清除enterChoice()的失败设置的情况下输入std::cin函数,此函数不会检查读取是否实际成功,因为流已经是在故障模式下。函数应该读取值并返回如下结果:

std::cin >> choice;
return std::cin? choice: ERROR;

由于createMasterFile()明确地将std::cin置于失败模式,因此您应该在尝试读取您的选择之前重置其状态,并且可能还会忽略当前行的其余部分:

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

当然,如果std::cin没有进一步的输入,那么阅读选项仍然会失败。