0

我一直在我的 C++ 编程书中做一个练习,它基本上要求我创建一个程序,该程序将包含 3 个文件,一个旧的客户数据主文件(帐户、名称、余额)、一个交易文件(帐户名称和贷方或借方),然后是合并这些文件并输出新的客户数据主文件的函数。我很确定我知道如何做到这一点,或者即使我不知道,我想我也能弄明白,我遇到的问题是一个简单的选择选择界面,它的实现与另一个工作的程序完全相同美好的。当我第一次运行程序时,它会让我输入一个选项(int),然后运行适当的函数(其中我只有 1 个完全实现,即 createMasterFile 函数。然后点击 switch 语句,它以某种方式将选择更改为 0,然后点击默认情况,然后返回到 while 语句,并且选择的值为 32767,并且似乎再次跳过了 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 天来找到一些答案。

提前致谢。

-鲍比

4

1 回答 1

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,读取选择仍然会失败。

于 2013-08-17T02:11:52.670 回答