0

I need some advice or hints about how to calculate the average of insurance, tax, gross and net salary. Just need some enlightment. Tried to add average function before but it seems that its hard to get the value from other function. Any ideas? This code is used to find the salary of employee and its average.

char EmpName[50];
int EmpID, EmpAge, EmpNum, i;
float gross_salary, net_salary;
float insurance, tax, total, total_insurance, total_tax;


int main()
{
    int i;
    FILE *file;

    file = fopen("UserDetails.txt", "wt");

    printf("Number of Employee to process: ");
    scanf("%d", &EmpNum);

    i = 1;
    EmployeeName: while( i <= EmpNum)
    {
        printf("\nEmployee name: "); scanf("%s", &EmpName);
        if (strlen(EmpName) <= 50){
            EmployeeID: printf("Employee ID: "); scanf("%d", &EmpID);
            if (EmpID >= 1000 && EmpID <= 9999){
                EmployeeAge: printf("Employee Age: "); scanf("%d", &EmpAge);
                if (EmpAge >= 18 && EmpAge <= 99){
                    printf("Employee Salary: "); scanf("%g", &gross_salary);
                    if (gross_salary >= 0.0 && gross_salary <= 9999.99){
                        goto Total;
                    }
                }
                else{
                    printf("\nInvalid Input!\nEmployee Age Is Between 18 To 99\n");
                    goto EmployeeAge;
                }
            }
            else{
                printf("\nInvalid Input!\nEmployee ID Number is Between 1000 To 9999\n");
                goto EmployeeID;
            }
        }
        else{
            printf("\nInvalid Input!\nMax Character is 50\n");
            goto EmployeeName;
        }

        Total: printf("\n");
        SetInsurance(EmpAge);
        IncomeTax(gross_salary);
        TaxDeduction(tax);
        InsuranceDeduction(insurance);
        NetSalary();
        Average(insurance,gross_salary,net_salary);
        i++;


        fprintf(file, "Employee name: %s\n", EmpName); //print data inside file
        fprintf(file, "Employee ID: %d\n", EmpID);
        fprintf(file, "Employee Age: %d\n", EmpAge);
        fprintf(file, "Employee Salary: %g\n\n", gross_salary);

    }


    fclose(file);
}

float SetInsurance(int x){
    while (i <= EmpNum){
        if (x <= 35)
            insurance = 110;
        else if (x >=36 && x <= 65)
            insurance = 160;
        else if (x > 65)
            insurance = 250;
        else
            printf("Under Age!");
        total = insurance;
        printf("\nInsurance: %.2f\n", total);
        return total;i++;
    };
}

float IncomeTax(float salary) {
    int i = 0;
    while(i < EmpNum){
        if (salary <= 999.99)
            tax = 0;
        else if (salary >= 1000 && salary <= 2999.99)
            tax = 2.5;
        else if (salary >= 3000)
            tax = 5;
        else
            printf("Invalid Input!\n");
        printf("Income Tax Rate: %.2f%\n", tax);
        return tax;
        i++;
    }
}

float InsuranceDeduction(float insurance){

    if (insurance == 110){
        total_insurance =+ 110;
    }else if (insurance == 160){
        total_insurance =+ 160;
    }else if (insurance == 250){
        total_insurance =+ 250;
    }
    return total_insurance;
}

float TaxDeduction(float tax){
    if(tax == 2.5){
        total_tax = gross_salary * 0.025;
    }else if(tax == 5){
        total_tax = gross_salary * 0.05;
    }
    return total_tax;
}

void NetSalary(){
    total = TaxDeduction(tax) + InsuranceDeduction(insurance);
    net_salary = gross_salary - total;
    printf("Net Salary: RM%.2f\n", net_salary);
}

2 Answers2

0

"I need some advice or hints., ...,any idea?"

First: Read and act on each of suggestions in first 3 comments under your post from @Chux.

Other suggestions:
Avoid using goto tag ... :tag statements to traverse code.

Create functions that can be called to do a simple task, then return.

Use a struct to contain related data when there can be more that one related data set.

Change

char EmpName[50];
int EmpID, EmpAge, EmpNum, i;
float gross_salary, net_salary;
float insurance, tax, total, total_insurance, total_tax;  

To for example: (Note, not all these members may be necessary, depending on how you finally implement the records needed for each employee.)

typedef struct {
    char EmpName[50];
    int EmpID; 
    int EmpAge;
    double gross_salary;
    double net_salary;
    double insurance;
    double total_insurance; //may not be necessary in struct
    double tax;
    double total_tax; //may not be necessary in struct
}account_s;

Note, if "total" members are to be used as totals for all employees, then they should probably not be a members in the struct.

Create instance(s) of this struct in local space, Eg.

int main(void)
{
    int EmpNum = 0;
    ... 
    printf("Enter number of Employees to process: ");
    scanf("%d", &EmpNum);
    account_s account[EmpNum];//creates an array of instances of account_s
    memset(account, 0, sizeof account);//initializes array

Incorporate account_s into functions as return type, and/or function parameters. Eg.

The following is a very brief, but compilable and runable example to illustrate several things including how to pass a single function argument containing all the information needed to update and contain employee information (via struct).

//prototypes
void populateAccounts(int count, account_s record[count]);
void SetInsurance(account_s *record);
double Get_ave_salery(int c, account_s *account);

int main(void)
{
    int EmpNum = 0;

    printf("Number of Employee to process: ");
    scanf("%d", &EmpNum);
    account_s account[EmpNum];//creates an array of instances of account_s
    memset(account, 0, sizeof account);//initializes array
    
    populateAccounts(EmpNum, account);
    double ave_salary = Get_ave_salery(EmpNum, account);
    printf("Average Gross Salary: %lf\n", ave_salary);
    
    return 0;
}

void populateAccounts(int count, account_s record[count])
{
    //Read in information for each account
    for(int i=0; i<count; i++)
    {
        printf("\nEnter employee name: "); 
        scanf("%s", record[i].EmpName);
        printf("\nEnter employee ID: "); 
        scanf("%d", &record[i].EmpID);
        printf("\nEnter employee Age: "); 
        scanf("%d", &record[i].EmpAge);
        printf("\nEnter employee Salary: "); 
        scanf("%lf", &record[i].gross_salary);
        SetInsurance(&record[i]);//function to set insurance via function argument
        // etc.
    }
}

void SetInsurance(account_s * record){

    if (record->EmpAge <= 35)
        record->insurance = 110;
    else if (record->EmpAge >=36 && record->EmpAge <= 65)
        record->insurance = 160;
    else if (record->EmpAge > 65)
        record->insurance = 250;
    else
        printf("Under Age!");
   // total = record->insurance;
    printf("\nInsurance: %.2f\n", record->insurance);

}

double Get_ave_salery(int c, account_s *account)
{
    double ave = 0.0;
    double sum = 0.0;
    for(int i=0; i<c; i++)
    {
        sum += account[i].gross_salary;
    }
        
    return sum/c; 
}         

There is more for you to do here, but this should help you to get started.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • I don't quite understand the difference between the arrow (->) and the dot (.). – eccentric learner Jan 07 '22 at 09:44
  • @eccentriclearner, the arrow `->` is used when you are dereferencing a pointer, and makes `p->field_name` equivalent to `(*p).field_name` (this last expression has low readability and is a bit embarrasing) – Luis Colorado Jan 07 '22 at 11:15
  • @eccentriclearner - I agree with Luis' summary. And there is [more detail here](https://stackoverflow.com/a/5998616/645128) for that question. Be sure to read some of the other answers as well. There are several good descriptions there to help you understand the differences between when to use `.` and when to use `->`. – ryyker Jan 07 '22 at 14:41
0

I order to solve the problem you face, I'd follow the recomendations you have received from other responses, and in addition:

If you fopen() a file, just check that the returned pointer is valid, as you can have several errors derived of:

  • Not having permissions to read the file.
  • file doesn't exist.

and these should be handled before you start processing the file.

Second, You don't need to store the data from the file, except for error purposes (it's preferable if you say that Martina Navratilova cannot be paying such ridiculous amount of taxes than saying that record 6437 in the file has a ridiculous amount of taxes to be payd -- you should search for it by counting, while your program has already done it)

If I would to decide how the input file is formatted, I should make a two line record, one line to specify the user name (which so, can have spaces embedded, as the new line marks the end of the name) so it can be read with fgets(), and a second line with all the numeric data you are going to fscanf(), after the sequence is done, you have all the data for a single user. Another possibility (to allow the name with spaces) is to put the name as the last field of the data file, so you can read all the last field characters upto the \n as the user name. This would allow to put each user in one single line

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31