-3

I need to enter info and calculate some stuff for several employees, and output every employees information into single console, and I need to use arrays.

Problem is I don't really know how to store information from the loop into an array. Screenshot of exercise is here

I ask the user how many workers there are, and the value goes into "workers" variable, then I create int employees[workers] array, so the number of iterations in the loop is determined by user's input.

The problem with my loop is that it does not reiterate the questions no matter how many employees there are.

I used do while loop and "Count" variable to control the number of reiterations, but after entering the info once, it just shows the result, instead of asking the questions again.

I also tried while loop and "count" variable, but this time it asks only how many employees there are and it just shows empty output.

int main()
{
//************************DECLARATIONS**********************

    typedef char INFO;

    INFO f_name[30];
    INFO m_name[10];
    INFO l_name[30];

    int count; // tracks the number of iterations in do loop
    int workers;
    double rate;
    double hrs_worked;
    double gross_inc;
    double overtime;
    double tax_total;
    float net;

    float STATE_TAX;
    float FED_TAX;
    float UNI_FEE;
    const double OVERTIME_R = 1.5;

//*****************INPUT FROM USER***************************
    cout << "Enter amount of workers" << endl;
    cin >> workers;

    int employees[workers];

    while(count < workers)
    {

        cout << "Enter worker's First name: " << endl;
        cin.getline(f_name, (sizeof(f_name)-1));

        cout << "Enter worker's middle name initial: " << endl;
        cin.getline(m_name, (sizeof(m_name)-1));

        cout << "Enter worker's last name: " << endl;
        cin.getline(l_name, (sizeof(l_name)-1));

        cout << "Enter number of hours worked: " << endl;
        cin >> hrs_worked;

        // If statement activates if user enters incorrect values
        // and asks to reenter the correct value.
        if(hrs_worked < 0 || hrs_worked > 60)
        {
            while(hrs_worked < 0 || hrs_worked > 60)
            {
                cout << "Must be between 0 and 60: " << endl;
                cin >> hrs_worked;
            }
        }

        cout << "Enter Rate Per Hour: " << endl;
        cin >> rate;

        // If statement activates if user enters incorrect values
        // and asks to reenter the correct value.
        if(rate < 0 || rate > 50)
        {
            while(rate < 0 || rate > 50)
            {
                cout << "Must be between 0 and 50: " << endl;
                cin >> rate;
            }
        }
        count++;
    }
    system("clear");
//**********************************CALCULATIONS*****************
    // Calculates overtime if employee worked more than 40 hrs

    if(hrs_worked > 40)
    {
        overtime = (hrs_worked - 40.0) * rate * OVERTIME_R;
    }

    gross_inc = (rate * hrs_worked) + overtime;
    STATE_TAX = gross_inc * 0.06;
    FED_TAX = gross_inc * 0.12;
    UNI_FEE = gross_inc * 0.02;
    tax_total = STATE_TAX + FED_TAX + UNI_FEE;
    net = gross_inc - (tax_total)


    return 0;
}   

At the moment priority is to set up a correct loop and store information from the loop into an array. Output is not the main focus at this point.

ray
  • 5,454
  • 1
  • 18
  • 40

2 Answers2

1

The first problem is that you need to understand what happened in this line:

    int count; // tracks the number of iterations in do loop

You can simply output the value of this variable:

    cout << "count: " << count << endl;

And after that you should read a little bit about defining and declaring variables in C++ (it is not the same "operation").

If you need just a simple solution I can tell you that your count variable will have some "garbage" value. The easiest way to resolve it is to initialize it to the starting value. After analyzing the context I can suppose that int count = 0; will be the proper starting value.

I guess that there can be other problems but this one is directly related to your question.

I wish you good luck with C++! I also suggest you to dig in the C++ fundamentals, starting with understanding what's the definition and declaration of variables.

[UPDATE]

I want to add a little bit after you published your update:

    int i; // will be used in for loop

Please DON'T do that. If you want it to use inside the "for loop" then initialize it there.

    int workers = 0;

If this variable means "number of workers" you should name it accordingly to its meaning, e.g.

    int numberOfWorkers = 0;

Your problem comes from this li(n)e(s):

    // typedef for string data types    
    typedef char INFO;

Unfortunately you lie to yourself in this comment. This is not the string type. Your typedef is an alias of a char so it stores only a single character, not a string.

It should be

    // typedef for string data types    
    typedef char* INFO;

But in my humble opinion it's redunant since typename INFO says nothing. Also you must remember that if you want to fix this, you must also set some fixed size for these c-string members (f_name, m_name, l_name) because c-strings are meant to have constant size.

There is another one solution - if you want to code in C++, prefer std::string over c-strings. In brief, std::string works like a dynamic size array / container for char type elements.

Also you can simply replace c-style "dynamic" array:

    struct employee *emp = new employee[workers];

with e.g. std::vector:

    std::vector<employee> emp;
    emp.reserve(workers);

(also there is no need to use struct keyword in this line).

Another bug happens in all input checks, e.g.:

    while(emp[i].hrs_worked < 0 || emp[i].hrs_worked > 60)
    {
        cout << "Must be between 0 and 60: " << endl;
        cin >> emp[i].hrs_worked;
    }

It causes infinite loop (I checked it). Why? Because you didn't clean the input buffer, example here: How do I flush the cin buffer?

I think you can also consider changing this struct into class and consider overloading i/o stream operators (operator<< and operator>>) for your class which will simplify i/o operations on employee objects.

And the last remark - please publish your update by editing previous question rather than putting it as an answer.

And once more - I wish you good luck learning C++!

Matt Black
  • 31
  • 1
  • 4
  • I want to disagree with you, but i can't, because from your perspective everything you've said is absolutely correct haha. Thing is that I just came back to C++ after a year and i've forgotten a lot of things. This exercise has made me remember most of the stuff and also taught me alot. – David Gordeladze Jan 25 '19 at 09:51
  • I did manage to make it work. I edited pretty much most of the code. I'll upload corrected version in the morning. – David Gordeladze Jan 25 '19 at 09:52
  • @DavidGordeladze Please tell me why you want to disagree with me and what is wrong in your opinion? I'm just curious. – Matt Black Jan 25 '19 at 11:02
0

[UPDATE] Basically, the code was garbage, however it made me remember and learn lots of things. so this is how I remade the code:

I used utilized struct, pointer and "new" operator.

The only problematic part is this input part, because if I enter more than one character, the program basically skips everything, and just shows a template :

cout << "Enter first name of employee    "<<i+1<<" : " << endl;
cin  >> emp[i].f_name;

cout << "Enter middle name of employee   "<<i+1<<" : " << endl;
cin  >> emp[i].m_name;

cout << "Enter last name of employee     "<<i+1<<" : " << endl;
cin  >> emp[i].l_name;

cout << "Hours of work by employee " << i+1 << ": " << endl;
cin >> emp[i].hrs_worked;

this is what output looks like : output

//*********************** Preprocessor Directives *********************
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string.h>
#include <cmath>
#include <stdlib.h>
#include <string.h>

using namespace std;

// Constants
const double OVERTIME_R = 1.5;
#define STATE_TAX 0.06
#define FED_TAX 0.12
#define UNION_FEE 0.02

// typedef for string data types
typedef char INFO;

// using struct to store employee info
struct employee
{
    INFO f_name;
    INFO m_name;
    INFO l_name;
    float rate;
    float hrs_worked;
    float gross;
    float overtime;
    float state_tax;
    float fed_tax;
    float uni_fee;
    float net;
};

//******************************* main ********************************

int main()
{

    int workers = 0;
    int i; // will be used in for loop
    float total_gross = 0;
    float avg_gross = 0;

//*****************Process***************************

    // asking number of employees
    cout << "Enter the number of employees: " << endl;
    cin >> workers;

    // array of employees
    struct employee *emp = new employee[workers];

    for(i = 0; i < workers; i++)
    {

        cout << "Enter first name of employee    "<<i+1<<" : " << endl;
        cin  >> emp[i].f_name;

        cout << "Enter middle name of employee   "<<i+1<<" : " << endl;
        cin  >> emp[i].m_name;

        cout << "Enter last name of employee     "<<i+1<<" : " << endl;
        cin  >> emp[i].l_name;

        cout << "Hours of work by employee " << i+1 << ": " << endl;
        cin >> emp[i].hrs_worked;

        // If statement activates if user enters incorrect values
        // and asks to reenter the correct value.
        if(emp[i].hrs_worked < 0 || emp[i].hrs_worked > 60)
        {
            while(emp[i].hrs_worked < 0 || emp[i].hrs_worked > 60)
            {
                cout << "Must be between 0 and 60: " << endl;
                cin >> emp[i].hrs_worked;
            }
        }

        cout << "Rate Per Hour of employee " << i+1 << ": " << endl;
        cin >> emp[i].rate;

        // If statement activates if user enters incorrect   >> values
        // and asks to reenter the correct value.
        if(emp[i].rate < 0 || emp[i].rate > 50)
        {
            while(emp[i].rate < 0 || emp[i].rate > 50)
            {
                cout << "Must be between 0 and 50: " << endl;
                cin >> emp[i].rate;
            }
        }

        // if employee has worked over 40 hrs. this statement activates.
        if(emp[i].hrs_worked > 40)
        {
            emp[i].overtime = (emp[i].hrs_worked - 40.0) * emp[i].rate *         
OVERTIME_R;
        }

        // Calculating the taxes.
        emp[i].state_tax = emp[i].gross * STATE_TAX;
        emp[i].fed_tax = emp[i].gross * FED_TAX;
        emp[i].uni_fee = emp[i].gross * UNION_FEE;
        emp[i].net= emp[i].gross - (emp[i].state_tax + emp[i].fed_tax +                 
  emp[i].uni_fee);

        // Total Gross
        total_gross += emp[i].gross;
    }

//**********************************OUTPUT****************************
    cout << endl;
    cout << endl;
    cout << "\t\t\t\t" <<"Data Housing Corp. Weekly Payroll" << endl;
    cout << "\t\t\t\t" <<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    cout << "First Name" << setw(5) << "MI" << setw(13) << "Last Name" <<     setw(18)
         << "Rate per hour" << setw(18)<< "Hours worked" << setw(12)<< "Overtime"
         << setw(10)<< "Gross" << setw(15)<< "State tax"
         << setw(10)<< "Fed tax" << setw(15)<< "Union fee" << setw(10)<< "Net" << endl;
    cout << "==========" << setw(5) << "==" << setw(13) << "=========" <<     setw(18)
         << "=============" << setw(18)<< "============" << setw(12)<< "========"
         << setw(10)<< "=====" << setw(15)<< "========="
         << setw(10)<< "=======" << setw(15)<< "=========" << setw(10)<< "==="     << endl;

for ( i = 0  ; i < workers ;  i++)
    {
        cout << setw(10) << emp[i].f_name << setw(5) << emp[i].m_name << setw(13)
        << emp[i].l_name << setw(18) << emp[i].rate << setw(18)<<     emp[i].hrs_worked
        << setw(12)<< emp[i].overtime << setw(10)<< emp[i].gross << setw(15)
        << emp[i].state_tax << setw(10)<< emp[i].fed_tax << setw(15)<< emp[i].uni_fee
        << setw(10) << fixed << showpoint <<setprecision(2)<< emp[i].net << endl;
    }
    return 0;
}