Hello,

I am trying to read data from a text file in the following format:
05 mike smith 30.00 2 1

so the format is: int, character[21] = max size of array, double, int, int

I am trying to read the values into an array of objects. I can read the first int and the name fine but I can't read in the rest of the values. Heres my code:

numEmp = 0;
    empFile >> id;
    empFile.ignore(); // Discard space before name
    empFile.getline(name, 21, '\n'); // Store up to 20 characters
    empFile >> rate >> dep >> type; //I think this is the problem
 
    while (empFile && numEmp < MAX_EMP)
    {
         // Move new employee info into array and increment numEmp count
         Emp[numEmp].set(id, name, rate, dep, type);
         numEmp++;
 
         // Get next employee info
         empFile >> id;
         outputFile << id << endl;
         empFile.ignore(); // Discard space before name
         empFile.getline(name, 21, '\n'); // Store up to 20 characters
         empFile >> rate >> dep >> type;
    }

Line 3 can be deleted because the stream's extraction operaotr >> will ignore all white space (spaces and tabs) between words.

Line 4: you don't want to use getline() here because it reads the entire line, not just the next two words. If the name is always in the format you show then its probably better and easier to use the extractions operator >> to read the first name and last name separately.

string firstName,lastName;
empFile>> firstName >> lastName;
// now concantinate them together
string name = firstName + " " + lastName;

line 5 should work ok if you make the above changes

Thanks for the response.

The only problem is that I need to ultimately store the name, both first and last name into a character array which is apart of a class object. I tried

strcpy(name, tempName); //where tempName is a string

I get an error with that syntax; what is the correct way to copy a string into an array?

Also, is it possible to take in the entire line of input into one array and then extract the specific variables?

Thanks

I got around the issue of copying the string into an array using the following code:

// tempName is a string, name is an array of characters
 tempName.copy(name, 21, 0);

I am only able to copy in the first line of data from the text file but not the rest. For some reason, it is not looping until empFile && empNum are less than MAX_EMP:

[LIST=1]
[*]const int MAX_EMP = 100;
[*]int numEmp = 0;
[*]empFile >> id;
[*]empFile >> firstName >> lastName; // Extract first and last name
[*]tempName = firstName + " " + lastName; // Concantinate both names
[*]tempName.copy(name, 21, 0);
[*]empFile >> rate >> dep >> type; // Extract rest of varbiables
[*]while (empFile && numEmp < MAX_EMP)
[*]{
[*]// Move new employee info into array and increment numEmp count
[*]Emp[numEmp].set(id, name, rate, dep, type);
[*]numEmp++;
[*]// Get next employee info
[*]empFile >> id;
[*]empFile >> firstName >> lastName; // Extract first and last name
[*]tempName = firstName + " " + lastName; // Concantinate both names
[*]tempName.copy(name, 21, 0);
[*]empFile >> rate >> dep >> type; // Extract rest of varbiables
[*]}[/LIST]

Rockthrower, don't manually use

  • bbcode to create line numbers. Instead use

or [code=cplusplus] bbcode.[code=c] or bbcode.[code=cplusplus] bbcode.

I realized that it was not looping because i was not taking in the very last character in the line. I initialized a new variable to take in the last character and although it loops now, it still does not loop through the entire file nor does it read the correct numbers after the double amount. Below is a sample of the text file I am reading in:

5 Christine Kim 30.00 2 1 F
15 Ray Allrich 10.25 0 0 M
16 Adrian Bailey 12.50 0 0 F
17 Juan Gonzales 30.00 1 1 M
18 Morris Kramer 8.95 0 0 M

The first integar, the name and the double amount are stored correctly but the last two integars and the last character are not stored correctly. My revised code is:

numEmp = 0;
empFile >> id;
empFile >> firstName >> lastName; // Extract first and last name
tempName = firstName + " " + lastName; // Concantinate both names
tempName.copy(name, 21, 0); // Copy string into array called name
empFile >> rate >> type >> sex; // Extract the rest of the variables in line
 
while (empFile && numEmp < MAX_EMP)
    {
         // Move new employee info into array and increment numEmp count
         Emp[numEmp].set(id, name, rate, dep, type);
         numEmp++;
 
         // Get next employee info
         empFile >> id;
         empFile >> firstName >> lastName; // Extract first and last name
         tempName = firstName + " " + lastName; // Concantinate both names
         tempName.copy(name, 21, 0); // Copy string into array called name
         empFile >> rate >> type >> sex; // Extract the rest of the variables in line
    }

does Emp.set() copy name into another class variable? If it does then you don't neet 6 or 19, but you can use string's c_str() method instead to pass a char* to that function, like this:

Emp[B][[/B]numEmp[B]][/B].set[B]([/B]id, tempName.c_str(), rate, dep, type[B])[/B];

I think you will need to post the rest of your program so we can see class declaration and other code. What you posted appears to be ok so the problem is probably elsewhere.

Also, "are not stored correctly" does not give enough information. Explain what actually does happen, because the result of the error may be important to understanding the problem.

OK, so this program that I am writing basically reads data from a text file then stores the data into an array of objects - one object per line. It then makes the necessary calculations and outputs the results to a file. I managed to get the program to work but I still have problems reading in the data.

Firstly, I am currently taking in the names in the text file into a string and the problem with this is when there is a name with a format such as: "J. p morgan" because i have set aside only two strings, one for the first name and one for the second name, and so when the program attempts to read such a name, the next line is not read in correctly.

Also, for some reason I am not able to read in the full double amount such as 45.55. only 45.5 is stored and not the entire amount although I am using a double variable to store it.

And finally, the last lines in each list is stored twice for some reason in my output file.

So the bottomline is that I need a consistent and efficient way of reading in an entire line from the text file correctly.

I am reading in from two seperate files, one file has the following format:

5 Christine Kim 30.00 2 1 F
15 Ray Allrich 10.25 0 0 M
16 Adrian Bailey 12.50 0 0 F
17 Juan Gonzales 30.00 1 1 M
18 Morris Kramer 8.95 0 0 M
22 Cindy Burke 15.00 1 0 F
24 Esther Bianco 10.25 0 0 F
25 Jim Moore 27.50 3 1 M
32 Paula Cameron 14.50 0 0 F
36 Melvin Ducan 10.25 0 0 M
37 Nina Kamran 30.00 1 1 F
38 Julie Brown 35.00 0 1 F
40 Imelda Buentello 14.50 0 0 F
43 Maria Diaz 15.00 0 0 F
42 J. P. Morgan 12.50 0 0 M

So for example, if the line is "42 J. P. Morgan 12.50 0 0" I need to extract "42", "J. P. Morgan", "12.50", "0", "0"

The other text file has this format:

17 20.0
37 31.0
5 40.0
42 39.5
24 15.0
22 40.0
15 42.0
18 40.0
25 45.0
32 25.0
40 47.5
36 -40.0
16 40.0
38 35.0
43 40.0
33 30.0

This is my entire code:

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
//Class
class EmpInfo
{
private:
int empId; // Used to store employee id
char empName[21]; // Used to store employee name
double empPayrate; // Used to store employee's pay rate
int empDep; // Used to store employee's dependents
int empType; // Used to store employee type
 
public:
EmpInfo();
EmpInfo(int, char[], double, int, int);
void set(int, char[], double, int, int);
int getID();
const char *getName();
double getPayrate();
int getDep();
int getType();
 
 
}; // End of class
EmpInfo::EmpInfo()
{
empId = 0;
strcpy( empName, "");
empPayrate = 0.0;
empDep = 0;
empType = 0;
}
EmpInfo::EmpInfo(int Id, char name[], double rate, int dep, int type)
{
set(Id, name, rate, dep, type);
}
void EmpInfo::set(int Id, char name[], double rate, int dep, int type)
{
empId = Id;
strcpy(empName, name);
empPayrate = rate;
empDep = dep;
empType = type;
}
int EmpInfo::getID()
{
return empId;
}
const char *EmpInfo::getName()
{
return empName;
}
double EmpInfo::getPayrate()
{
return empPayrate;
}
int EmpInfo::getDep()
{
return empDep;
}
int EmpInfo::getType()
{
return empType;
} 
const int MAX_EMP = 100; // Max number of employees
int search(int, EmpInfo[], int);
double printReport(int, EmpInfo[], ofstream&, int);
double calcGrosspay(int, EmpInfo[], int);
int main()
{
EmpInfo Emp[MAX_EMP]; // Declare array of structs
int numEmp; // employees counter
int transNum; // transaction counter
ifstream empFile; // Establish input file stream
ofstream outputFile; // Establish output file stream
string firstName; // Used to extract employee's first name
string lastName; // Used to extract employee's first name
string tempName; // Store first and last name
int id; // Used to store employee id
char name[21]; // store name in character array to send to object class
double rate; // Used to store employee's pay rate
int dep; // Used to store employee's dependents
int type; // Used to store employee type
int hours; // Number of hours worked by employee
 
//Open employee file
empFile.open("master.txt");
 
//Make sure file exists/opens
if (!empFile)
{
cout << "Can not open employee file \"master.txt\"" << endl;
return 1;
}
 
numEmp = 0;
empFile >> id;
empFile >> firstName >> lastName; // Extract first and last name
tempName = firstName + " " + lastName; // Concantinate both names
tempName.copy(name, 21, 0); // Copy string into array called name
empFile >> rate >> dep >> type;
empFile.ignore(999, '\n');
 
while (empFile && numEmp < MAX_EMP)
{
// Move new employee info into array and increment numEmp count
Emp[numEmp].set(id, name, rate, dep, type);
numEmp++;
 
// Get next employee info
empFile >> id;
empFile >> firstName >> lastName; // Extract first and last name
tempName = firstName + " " + lastName; // Concantinate both names
tempName.copy(name, 21, 0); // Copy string into array called name
empFile >> rate >> dep >> type;
empFile.ignore(999,'\n');
}
 
empFile.clear();
//close masterfile
empFile.close();
 
// open transaction file
empFile.open("trans.txt");
 
//Make sure file exists/opens
 
transNum = 0;
empFile >> id;
empFile >> hours;
empFile.ignore(999,'\n');
 
// output invalid transactions
outputFile.open("report.txt");
 
// Print header to file
outputFile << setw(10) << "ID:" << setw(20) << "NAME:" << setw(10) << "TAX:"
<< setw(15) << "INSURANCE:" << setw(15) << "GROSS PAY:" << setw(15) << "NET PAY:" << endl;
outputFile << setw(10) << "---" << setw(20) << "-----" << setw(10) << "----" << setw(15) << "----------"
<< setw(15) << "----------" << setw(15) << "--------" << endl;
 
// Print Error and Control Report Header
cout << "INVALID TRANSACTIONS:" << endl;
cout << "---------------------" << endl;
cout << endl;
cout << setw(5) << "ID:" << setw(15) << "HOURS:" << endl;
cout << setw(5) << "---" << setw(15) << "------" << endl;
 
int correct;
double netPayTotal;
double grossPayTotal;
while (empFile && transNum < MAX_EMP)
{
// search to see if id is valid
int check = search(id, Emp, MAX_EMP);
 
if(check != -1 && hours >= 0)
{
netPayTotal += printReport(check, Emp, outputFile, hours);
grossPayTotal += calcGrosspay(check, Emp, hours);
correct++;
}
 
else
{
cout << setw(5) << id << setw(15) << hours << endl;
 
}
empFile >> id;
empFile >> hours;
empFile.ignore(999,'\n');
transNum++;
 
}
 
cout << endl;
cout << endl; 
// Print Error and Control Report Header
cout << "VALID TRANSACTIONS:" << endl;
cout << "-------------------" << endl;
cout << endl;
cout << setw(10) << correct << endl << endl;
 
outputFile << setw(70) << "----------" << setw(15) << "--------" << endl;
outputFile << endl;
outputFile << setw(55) << "Weekly Total:" << setw(15) << grossPayTotal << setw(15) << netPayTotal << endl;
outputFile << setw(55) << "-------------" << endl;
 
// Close outputfile
outputFile.close();
// Close inputfile
empFile.close();
 
system("PAUSE"); 
return 0; 
} 
 
int search(int val, EmpInfo list[], int length)
{
int index = 0;
while(index < length)
{
if(val == list[index].getID())
return index;
index++;
}
return -1; // id not found
}
 
double printReport(int index, EmpInfo Emp[], ofstream &outputFile, int hours)
{
double tax; // Tax amount for employee
double insurance; // Insurance cost for each employee
double grossPay; // Pay before insurance and tax
double netPay; // Net pay
 
// Calculate grossPay
grossPay = calcGrosspay(index, Emp, hours);
 
// Calculate tax
tax = grossPay * 0.15;
// Calculate insurance
insurance = 20.00 * Emp[index].getDep();
// Calculate netpay
netPay = ((grossPay - tax) - insurance);
 
// Output to file
outputFile << setw(10) << Emp[index].getID() << setw(20) << Emp[index].getName()
<< setw(10) << setprecision(2) << fixed << tax << setw(15) << setprecision(2)
<< fixed << insurance << setw(15) << setprecision(2) << fixed << grossPay 
<< setw(15) << setprecision(2) << fixed << netPay << endl;
 
return netPay; 
 
}// End of printReport function
 
double calcGrosspay(int index, EmpInfo Emp[], int hours)
{
double grossPay;
// If management employee or if hours <= 40
if (Emp[index].getType() == 1 || hours <= 40)
{
grossPay = (hours * Emp[index].getPayrate());
 
}
// If non-management employee or hours > 40
else
{
grossPay = ((40 * Emp[index].getPayrate()) + ((hours - 40) * 1.5 * Emp[index].getPayrate()));
 
}
return grossPay;
 
} // End of calcGrosspay functions

First of all, please format your code. It's nearly impossible to follow.

Firstly, I am currently taking in the names in the text file into a string and the problem with this is when there is a name with a format such as: "J. p morgan" because i have set aside only two strings, one for the first name and one for the second name, and so when the program attempts to read such a name, the next line is not read in correctly.

You can't use >> when reading a file with evil syntax like you have. Read an entire line using getline() and write a function to pull out and convert all the bits and pieces by looking at the line character by character.

And finally, the last lines in each list is stored twice for some reason in my output file.

Generally this is a problem with using .eof() when you loop through the file for reading. This is what happens, feof() is identical to .eof() .

Thanks for the tips!

I am needing to use a pointer to an array of objects in addition to dynamically allocating memory for the array of objects. For some reason, I keep getting error messages:

while (empFile && transNum < empCount)
{
// search to see if id is valid
check = search(id, Emp, empCount);
 
"cannot convert `EmpInfo*' to `EmpInfo**' for argument `2' 
to `int search(int, EmpInfo**, int)' "

// If ID and hours are both valid
if(check != -1 && hours >= 0)
{
// Calculate netpay total
netPayTotal += printReport(check, Emp, outputFile, hours);
 
"cannot convert `EmpInfo*' to `EmpInfo**' for argument 
`2' to `double printReport(int&, EmpInfo**, std::ofstream&, 
int&)' " 
 
// Calculate grosspay total
grossPayTotal += calcGrosspay(check, Emp, hours);
 
"cannot convert `EmpInfo*' to `EmpInfo**' for argument 
`2' to `double calcGrosspay(int&, EmpInfo**, int*)' "
 
correct++; // Increment number of correct transactions counter
}
 
// If ID or hours not valid print out the id and hours 
else
{
cout << setw(5) << id << setw(15) << hours << endl;
 
}
empFile >> id; // read in ID
empFile >> hours; // read in hours
empFile.ignore(999,'\n'); // ignore the rest of the line
transNum++; // increment counter 
 
}

Please use the PREVIEW button before SUBMITting your post so you can see yourself if it's readable...

Your errors are telling you to look at the definition of the function and see what you should be passing, but you are not. You are passing a pointer when the function wants a pointer to a pointer

This article has been dead for over six months. Start a new discussion instead.