program works once, but won't loop

Hello! new forum user and fairly new at c++
I have this program I've written for a class and it seems to do everything it needs to (output to the text file specified by user) but it seems to only work properly when I run it once. if I loop it, it will record the first output and keep outputting that same information.... here is my code(we use namespace std;), I need it to be able to loop while user choice value is != 0 and output line after line to text file until finished. we have to use enum types for the menu options.

any and all help would be appreciate, thanks ahead of time!

#include "header.h"

/**************************************************************************
* Functions & Arrays
*-------------------------------------------------------------------------
* This program reads in a list of items from a file, separates them into
* different data type arrays and does different calculations depending upon
* user choice of the menu options.
*-------------------------------------------------------------------------
* INPUTS :
* nameAr : Array for the name inputs.
* searchItem : Name the user searches for.
*****************************************************************/

int main()
{
const int AR_SIZE = 10;
const int S_WIDTH = 40;

ofstream oFile;
int balanceIndex;
int nameIndex;
int choice;
float sumOrAvg;
string name;
Menu enumChoice;

string inFileName;
string outFileName;

string nameAr[AR_SIZE];
int numIdAr[AR_SIZE];
float balanceAr[AR_SIZE];


// IN - prompts user for input file name
cout << left << setw(S_WIDTH) << "What input file would you like to use?";
getline(cin, inFileName);

// IN - prompts user for output file name
cout << setw(S_WIDTH) << "What output file would you like to use?";
getline(cin, outFileName);

// IN & PROC - reads in names, id numbers, and balances from the file
// input by user and assigns the elements to their respective arrays
ReadInputFile(inFileName, nameAr, numIdAr,
balanceAr, AR_SIZE);

cout << endl;

// IN - prompts user for choice from list of menu options
PrintMenu();
cin >> choice;
cin.ignore(1000, '\n');
cout << endl;

do{
// PROC - this function converts int choice to enum type "Menu" choice
if(choice > 0 && choice <= 5)
{
enumChoice = ConvertChoice(choice);
}
// PROC & OUT - error checks for valid input and loops until entered
else
{
cout << "**** INVALID INPUT, PLEASE TRY AGAIN!!! ****\n\n";
}
}while(enumChoice < 0 || enumChoice > 5);

oFile.open(outFileName.c_str());
oFile << setprecision(2) << fixed;
switch(enumChoice)
{
case LARGER : oFile << endl << "Larger Balance:\n";
case SMALLER: if(enumChoice == SMALLER)
{
oFile << endl << "Smaller Balance:\n";
}
oFile << setw(9) << left << "ID #" << setw(25) << "NAME";
oFile << "BALANCE DUE" << endl;
balanceIndex = SearchBalance(balanceAr, enumChoice,
AR_SIZE);
oFile << setw(9) << "-----";
oFile << setw(25) << "--------------------";
oFile << "-----------\n";

oFile << setw(9) << numIdAr[balanceIndex] << setw(25);
oFile << nameAr[balanceIndex] << "$" << setw(10) << right;
oFile << balanceAr[balanceIndex] << endl;

break;
case SUM : oFile << endl << "Sum of Balance for all persons:";
case AVERAGE: if(enumChoice == AVERAGE)
{
oFile << "Average Balance for all persons:";
}
sumOrAvg = SumOrAvg(balanceAr, enumChoice, AR_SIZE);
oFile << endl << "$" << setw(10) << right << sumOrAvg;
break;
case FIND : do{
cout << "Who do you want to search for (enter done to "
"exit): ";
getline(cin, name);

nameIndex = FindPerson(nameAr, name, AR_SIZE);
if(nameIndex < AR_SIZE)
{
cout << "Found.\n\n";

oFile << endl;
oFile << "Search Name:\n";
oFile << setw(9) << left << "ID #" << setw(25) << "NAME";
oFile << "BALANCE DUE" << endl;
oFile << setw(9) << "-----";
oFile << setw(25) << "--------------------";
oFile << "-----------\n";

oFile << setw(9) << numIdAr[nameIndex] << setw(25);
oFile << nameAr[nameIndex] << "$" << setw(10) << right;
oFile << balanceAr[nameIndex];

}
else if(nameIndex == AR_SIZE && name != "done")
{
cout << name << " was not found.\n\n";
}
}while(name != "done");
cout << endl << endl;
oFile << endl << endl;
oFile.close();
}

cout << "Thank you for using my program!";

return 0;
}

here is my functions.cpp:

#include "header.h"

/*************************************************************************
* ReadInputFile
* This function receives an input file name from the user and assigns each
* item in the file to its appropriate element type in the specified array
* ------------------------------------------------------------------------
* PRE-CONDITIONS
* inFileName: input file name is previously defined by user
*
* POST-CONDITIONS
* nameAr[]: retrieves names from input file and assigns them into each
* element of the array
*
* numIdAr[]: retrieves id numbers from input file and assigns them into
* each element of the array
*
* balanceAr[]: retrieves balances from input file and assigns them into
* each element of the array
**************************************************************************/
void ReadInputFile(string& inFileName, string nameAr[], int numIdAr[],
float balanceAr[], const int AR_SIZE)
{
int index;

ifstream inFile;

// PROC - program opens input file
inFile.open(inFileName.c_str());

// PROC - initializing index to 0 for arrays
index = 0;

// IN & PROC - while loop to read in names, ids, and balances, then
// stores them in the appropriate arrays
while (inFile && index < AR_SIZE)
{
getline(inFile, nameAr[index]);

inFile >> numIdAr[index];
inFile.ignore(1000, ' ');

inFile >> balanceAr[index];
inFile.ignore(1000, '\n');

// PROC - increment index
index++;
}

// PROC - program closes input file
inFile.close();

}

/*************************************************************************
* PrintMenu
* This function prints the menu option list for the user
* ------------------------------------------------------------------------
* PRE-CONDITIONS
* pre-determined output
*
* POST-CONDITIONS
* this function will print the menu option list when called
**************************************************************************/
void PrintMenu()
{
cout << "MENU OPTIONS\n\n";
cout << "1 - Find the larger balance\n";
cout << "2 - Find the smaller balance\n";
cout << "3 - Obtain the sum of all balances\n";
cout << "4 - Obtain the average of all balances\n";
cout << "5 - Find person\n";
cout << "0 - Exit\n";
cout << "Enter an option (0 to exit): ";
}

/*************************************************************************
* ConvertChoice
* This function converts the choice from int to enum type "Menu" and error
* checks for invalid choices
* ------------------------------------------------------------------------
* PRE-CONDITIONS
* choice - menu option that is input by user
*
* POST-CONDITIONS
* enumChoice - converted variable from int to enum type "Menu." Also
* error checks for valid inputs and loops until valid choice is input.
**************************************************************************/
Menu ConvertChoice(int choice)
{
Menu enumChoice; // PROC - converted variable from int to enum

// PROC & OUT - switch statement to determine proper conversion
switch(choice)
{
case 1 : enumChoice = LARGER;
break;
case 2 : enumChoice = SMALLER;
break;
case 3 : enumChoice = SUM;
break;
case 4 : enumChoice = AVERAGE;
break;
case 5 : enumChoice = FIND;
}

return enumChoice;
}

/*************************************************************************
* SearchBalance
* This function searches for the highest or lowest balance depending on the
* choice entered by the user and returns the index of type int
* ------------------------------------------------------------------------
* PRE-CONDITIONS
* balanceAr[]: parallel array traversed to find balance
* enumChoice : user choice of enumerated type "menu"
* AR_SIZE : size of array
*
* POST-CONDITIONS
* this function returns an index number as an integer
**************************************************************************/
int SearchBalance(const float balanceAr[], Menu enumChoice,
const int AR_SIZE)
{
int index;
int smallIndex;
int largeIndex;
float smallest;
float largest;

largest = balanceAr[0];
smallest = balanceAr[0];

for(index = 1; index < AR_SIZE; index++)
{
if(balanceAr[index] > largest)
{
largest = balanceAr[index];
largeIndex = index;

}
else if(balanceAr[index] < smallest)
{
smallest = index;
smallIndex = index;
}
}

if(enumChoice == LARGER)
{
return largeIndex;
}
else
{
return smallIndex;
}
}

/*************************************************************************
* SumOrAvg
* This function calculates the sum or average depending on user choice and
* returns the number as a float
* ------------------------------------------------------------------------
* PRE-CONDITIONS
* balanceAr[]: parallel array traversed to find balance
* enumChoice : user choice of enumerated type "menu"
* AR_SIZE : size of array
*
* POST-CONDITIONS
* this function returns a sum or average as a float depending on user
* choice
**************************************************************************/
float SumOrAvg(const float balanceAr[], Menu enumChoice,
const int AR_SIZE)
{
int index;
float sum;

sum = 0;

for(index = 0; index < AR_SIZE; index++)
{
sum += balanceAr[index];
}

if(enumChoice == SUM)
{
return sum;
}
else
{
return sum/10;
}
}

/*************************************************************************
* FindPerson
* This function searches for the person input by the user
* ------------------------------------------------------------------------
* PRE-CONDITIONS
* nameAr[]: parallel array traversed to find balance
* AR_SIZE : size of array
* name : name entered by user for search
*
* POST-CONDITIONS
* this function returns an index number as an integer for the person
* (if found)
**************************************************************************/
int FindPerson(const string nameAr[], string name, const int AR_SIZE)
{
int index;
bool found;

index = 0;
found = false;

while(index < AR_SIZE && !found)
{
if(nameAr[index] == name)
{
found = true;
}
else
{
index++;
}
}

return index;
}
You should use the code format tags to format any code you post.

I took the time to copy and format your code. It's well written, but there's one really important concept that you're missing, it's called RAII.

In C, and a whole bunch of derived languages, it's common to declare all your variables at the top of the function. And that's what you've done.

In C++, we don't do that. We declare variables where they're used.

Also, never call open/close on fstreams. Let the constructor/destructor do their job. So instead of writing code like this:
1
2
3
4
5
ofstream os;
// ...
os.open("output.txt");
// ...
os.close();

Try this:
1
2
3
4
{
	ofstream os("output.txt");
	// ...
}

This is a really important concept in C++ and is the reason why C++ does objects without a garbage collector.

Incidentally, it's the reason why your program isn't working.
Last edited on
thanks for your reply and time with this problem, unfortunately, I cannot declare variables while I initialize as it is not the style for our class. I did some more research and came to find out my problem lay within the member function call for ofile... when I adjusted it to oFile.open("output.txt", ios::out | ios::app), it worked perfectly.
Topic archived. No new replies allowed.