Hello everyone, part of my program is supposed to read from a text file into two arrays. Text file looks like this:
CD334455 U 100
BC223344 U 10
AB112233 A 134
EE555555 G 18
DE445566 U 122
First string is the student ID, next character is student title, and the last number is the classes taken. In the lines that contain 'U', I need to input the student ID into idNum[] array and the student title into classLevel[] array, than skip the rest of the line. The other lines without 'U' are ignored.
So far I am able to get all the 'U's into the proper array. When I do a test by outputting the array, I see that on some lines the first character of the student ID is missing. I'm not sure what I'm doing wrong here, please help. Thank you.
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
usingnamespace std;
// Global constants
const string EMP_NAME = "employee";
const string FAM_NAME = "family";
constchar EMPLOYEE = 'O';
constchar FAMILY = 'F';
constint MAX_ARRAY = 7;
const string IN_CREDIT_FILE = "CREDITS.txt";
const string OUT_CREDIT_FILE = "OUT_CREDITS.txt";
// prototypes
void display_header();
void readCreditFile (ifstream&, string [], char [], int&);
double averageExpense ();
double highestExpense ();
double aboveAverageExpense ();
void displayExpenses ();
//*************************************************************************
// FUNCTION: main
// DESCRIPTION: Asks user for a base number, then calls functions to read
// an exponent and compute the base raised to the exponent, and
// then displays the results. Loops, requesting numbers until
// user enters zero for base.
// OUTPUT: Return Value: 0 on success
// CALLS TO: GetPositiveNum, CalcAnswer
//*************************************************************************
int main()
{
//VARIABLES
int cnt = 0; // counter used for employee coverage
int cnt1;
// opening the text file medical.txt
ifstream inCreditData;
inCreditData.open(IN_CREDIT_FILE.c_str());
// array's
string idNum [MAX_ARRAY];
char classLevel [MAX_ARRAY];
// verification that file exists
if (!inCreditData)
{
cout << "The input data file does not exist!" << endl;
cout << "Please verify input file and run the program again!" << endl;
return 5;
}
// calling different functions to compute and display the results
else
{
cout << "File opened successfully! Reading file." << endl << endl;
readCreditFile (inCreditData, idNum, classLevel, cnt);
}
return 0;
}
void readCreditFile (ifstream& inCreditData, string idNum [], char classLevel [], int& cnt)
{
string studentId;
char ch; // temporarily store the first string in the file
bool arrayFull = false; // check to see if there is still space in the array idNum[]
// inCreditData >> studentId; // prime read
while(inCreditData && cnt <= MAX_ARRAY)
{
// getline(inCreditData, studentId);
inCreditData >> studentId >> ch;
if (ch == 'U')
{
idNum[cnt] = studentId;
classLevel[cnt] = ch;
inCreditData.ignore (100, '\n');
cnt++;
}
}
inCreditData.close();
return;
}
The first two times through the while loop will be read and stored correctly. But look what happens when reading the third line: AB112233 A 134
studentId will be AB112233 and ch will be 'A' so the body of the if statement is skipped. But this means your ignore() statement on line 79 is also skipped, so the next time through the loop studentId is 134 (the remainder of line three) and ch is 'E" (the first character on line four). This is your missing character. Continuing with the while loop we get studentId = E555555 and ch = 'G'. We again skip the ignore inside the if statement and the same thing happens again, so when we finally get a line we want to save on line 5 the first letter is already consumed by the stream. Just move the line inCreditData.ignore(100, '\n'); to a position immediately following the if statement and before the end of the while loop.
Another point: Instead of using the default ifstream constructor and then calling the open() method, you should just use the ifstream constructor that takes a filename:
change: ifstream inCreditData;
inCreditData.open(IN_CREDIT_FILE.c_str());
to: ifstream inCreditData(IN_CREDIT_FILE.c_str());
Better yet, depending on how new your compiler is, there is an ifstream constructor that takes a std::string as an argument and you wont need to call c_str() to convert to a c-style string.
However, if not U, what do you do? Nothing.
Therefore, the next read operation reads the number after the non-U as string and a character from the next line as level.
Thank you everyone for your response. These smaller issues seem to make programming very time consuming. I can see how the placement of certain lines of code can make a huge difference in the output of your program. Thank you Alrededor for your explanation, that really help me. I totally understand why that was happening now. Have a great day everyone.