-2

When I input from the file it will only read the last line of all the variables. I know i need to have an array to get it to read each line im just confused about how to make an array because our text book does not explain it will in a way i can understand. The text file looks like this:

10948 Carpenter Stewart 503-21-3387 L31 40.7

10949 Pleasance Marie 433-82-7832 L27 35

with an employee ID, last name, first name, social, pay code and hours worked. This is what my code looks like.

#include <iostream>
#include <fstream>    
#include <iomanip>
#include <string>

using namespace std;
int main()
{
int empID;
string lastName;
string firstName;
string social;
string payCode;
double hoursWorked;
string payCodeH;
double payRate;
int empCnt = 0;
double totalPay = 0.00;


ifstream timeSheet;
ifstream hourlyPay;

timeSheet.open("TimeSheet.txt");
hourlyPay.open("HourlyPay.txt");

if (!timeSheet || !hourlyPay)
{
    cout << endl << "Error Opening input file." << endl;

    return -1;

}
cout << fixed << setprecision(2) << endl;
timeSheet  >> empID >> lastName >> firstName >> social >> payCode >> hoursWorked;

while (!timeSheet.eof())
{

    timeSheet >> empID >> lastName >> firstName >> social >> payCode >> hoursWorked;
    empCnt++;
}
timeSheet.close();

cout << empID << " " << lastName << " " << firstName << " " << social;

}

Thank you for any help on this.

  • 2
    do one think at a time. If you don't know how to create an array then start with a simple code that creates an array and nothing else. Btw you probably want a `std::vector` instead of an array – 463035818_is_not_a_number Nov 30 '20 at 16:14
  • 3
    And you don't want this: `while (!timeSheet.eof())`. Please read [Why is `iostream::eof()` inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Ted Lyngmo Nov 30 '20 at 16:16

2 Answers2

1

You have some data for each employee that you want to read from a stream an store in an array so I suggest that you create a class for that data. The simplest class is a struct (which by default gives public access to all its members).

It could look like this:

struct employee {
    int empID;
    std::string lastName;
    std::string firstName;
    std::string social;
    std::string payCode;
    double hoursWorked;
};

You want to read from an open file to populate the member variables, so let's add a member function for that:

struct employee {
    std::istream& read(std::istream& is) { // read from any istream, like an ifstream
        is >> empID >> lastName >> firstName >> social >> payCode >> hoursWorked;
        return is;
    }

    // the member variables ...
};

Now, if you have an employee object, you can call the_object.read(timeSheet); to read the data from the stream.

Similarly, you could add a member function to write the data to a stream:

struct employee {
    std::ostream& write(std::ostream& os) const {
        os << empID << ' ' << lastName << ' ' << firstName << ' '
           << social << ' ' << payCode << ' ' << hoursWorked << '\n';
        return os;
    }

    // the rest of the members ...
};

With these simple functions, you can now read and write employees from/to streams and store them in some array-like object. Since the number of employees is unknown when you compile the program, I suggest storing the employees in a std::vector<employee>.

Note, that you shouldn't use while (!timeSheet.eof()) (why is explained here). Instead, you can check the state of your file stream object after you've tried to extract something from the stream. A file stream returns !fail() in boolean context which means that your loop should look like this:

while(timeSheet >> empID >> lastName >> firstName >> social >> payCode >> hoursWorked) {
    // extraction succeeded
}

Since the read() function we added above returns a reference to the stream it reads from, it can be used in the same way.

Full example:

#include <fstream>
#include <string>
#include <iostream>
#include <vector>

struct employee {
    std::istream& read(std::istream& is) {
        is >> empID >> lastName >> firstName >> social >> payCode >> hoursWorked;
        return is;
    }

    std::ostream& write(std::ostream& os) const {
        os << empID << ' ' << lastName << ' ' << firstName << ' '
           << social << ' ' << payCode << ' ' << hoursWorked << '\n';
        return os;
    }

    int empID;
    std::string lastName;
    std::string firstName;
    std::string social;
    std::string payCode;
    double hoursWorked;
};

int main() {
    std::vector<employee> employees;

    if(std::ifstream timeSheet("TimeSheet.txt"); timeSheet) {
        employee temp;
        while(temp.read(timeSheet)) {          // only enter loop if extraction works
            employees.push_back(temp);         // store this employee in the vector
        }
    } else {
        std::cout << "Could not open file.\n";
    }

    // print the employees
    std::cout << "Employees:\n";
    for(const employee& emp : employees) {
        emp.write(std::cout);
    }

    /* an alternative way of printing all employees:
    for(size_t i = 0; i < employees.size(); ++i) {
        employees[i].write(std::cout);
    }
    */
}

You can use a similar technique for the other files.

Ted Lyngmo
  • 37,764
  • 5
  • 23
  • 50
-2

Maybe you are trying to do this. You have to make an array for each of your data like this. I made for 20 values, If your data is more than 20 you can change it.

#include <iostream>
#include <fstream>    
#include <iomanip>
#include <string>



using namespace std;
int main()
{
    int empID[20];
    string lastName[20];
    string firstName[20];
    string social[20];
    string payCode[20];
    double hoursWorked[20];
    string payCodeH[20];
    double payRate[20];
    int empCnt = 0;
    double totalPay = 0.00;


    ifstream timeSheet;
    ifstream hourlyPay;

    timeSheet.open("TimeSheet.txt");
    hourlyPay.open("HourlyPay.txt");

    if (!timeSheet)
    {
        cout << endl << "Error Opening input file." << endl;

        return -1;

    }
    cout << fixed << setprecision(2) << endl;
 
    int count = 0;
    while (!timeSheet.eof())
    {

        timeSheet >> empID[count] >> lastName[count] >> firstName[count] >> social[count] 
        >> payCode[count] >> hoursWorked[count];
        empCnt++;
        count++;
    }
    timeSheet.close();


    for (int i = 0; i < count; i++)`enter code here`
          cout << empID[i] << " " << lastName[i] << " " << firstName[i] << " " << 
          social[i] << endl;
}
underscore_d
  • 5,331
  • 3
  • 29
  • 56
  • 3
    I wouldn't recommend that. Why separate arrays for information that clearly belongs together? – Ted Lyngmo Nov 30 '20 at 16:37
  • 1
    Yeah, that approach is only good for very specific situations where it's measurably an optimisation, which isn't going to be the case here, and it just creates opportunities for mismatches and wrong/undefined behaviour otherwise. – underscore_d Nov 30 '20 at 16:45
  • moreover, what if the file does contain more than 20 entries? At runtime it will be too late to change it to something higher. You will overflow the arrays. Also see [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – 463035818_is_not_a_number Nov 30 '20 at 17:49
  • Absolutely that's not recommended. I gave a solution if you guys are not allowed to use struct or classes. Otherwise that would be the best option. – Usama Javed Nov 30 '20 at 18:41