Home > Enterprise >  Why is my main function not executing correctly?
Why is my main function not executing correctly?

Time:12-08

I'm trying to scan a txt file and based on if some conditions are met, I want to print it out into another txt file. Here is my main function:

#include "Header.h"


int main(void) {
    int payment=0, hours_worked = 0, rate_per_hour = 0, overtime = 0, total_payment, min = 0, max = 0, average = 0;
    total_payment=0;
    double total = 0;
    Employee payroll[200];

    FILE* infile = fopen("payroll.txt", "r");
    FILE* outfile = fopen("paid.txt", "w");


    int i = 0;
    while (!feof(infile)) {
        fscanf(infile, "%s", &payroll[i].name);
        fscanf(infile, "%s", &payroll[i].title);
        fscanf(infile, "%s", &payroll[i].hours_worked);
        fscanf(infile, "%s", &payroll[i].payrate);

        if (payroll[i].title == 'B') {
            if (payroll[i].hours_worked > 40) {
                payroll[i].payment = 40 * payroll[i].payrate;
                payroll[i].payment  = (1.5 * payroll[i].payrate * (payroll[i].hours_worked - 40));
            }
            else
                payroll[i].payment = payroll[i].hours_worked * payroll[i].payrate;
        }
        else {
            if (payroll[i].hours_worked > 40) {
                payroll[i].payment = 40 * payroll[i].payrate;
                payroll[i].payment  = (1.8 * payroll[i].payrate * (payroll[i].hours_worked - 40));
            }
            else
                payroll[i].payment = payroll[i].hours_worked * payroll[i].payrate;
        }
        if (i == 0)
            min = payroll[i].payment;
        total =  payroll[i].payment;
        if (min > payroll[i].payment)
            min = payroll[i].payment;
        if (max < payroll[i].payment)
            max = payroll[i].payment;
        i  ;
    }
    average = total / i; 
    fprintf(outfile, "total: $%.2lf\n average: $%.3lf\nMAx: $%.3lf\n Min: $%.2lf", total, average, max, min);

    fclose(infile);
    fclose(outfile);
    return 0;
}

Header file:


#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>


typedef struct employee

{

       char name[100];      // employee's name - last, first

       char title;          // title 'B' or 'M'

       double hours_worked; // total number of hours worked

       double payrate;      // pay rate per hour

       double payment;      // total payment for the pay period – you will compute!

} Employee;




#endif

payroll.txt, scanning this file:

Smith, Susan

B

80.0

17.76

Sanders, Fred

M

87.25

23.45

Kerr, Heidi

M

80.0

47.86

Russo, Rick

B

83.75

12.15

outputing to paid.txt:

total: $8098405204118553210089249756384123022462475737784054204141978203412550137716411406580975068756992904139218004071573362835456.00
 average: $0.000
MAx: $0.000
 Min: $0.00

problem is I wasn't expecting it to print out the total that much and the average, max, and min are all 0s.

CodePudding user response:

Off topic, but...
Why do you want to "bulk-up" your code with copy/paste/adapt of codeblocks?

All of this:

if (payroll[i].title == 'B') {
    if (payroll[i].hours_worked > 40) {
        payroll[i].payment = 40 * payroll[i].payrate;
        payroll[i].payment  = (1.5 * payroll[i].payrate * (payroll[i].hours_worked - 40));
    }
    else
        payroll[i].payment = payroll[i].hours_worked * payroll[i].payrate;
}
else {
    if (payroll[i].hours_worked > 40) {
        payroll[i].payment = 40 * payroll[i].payrate;
        payroll[i].payment  = (1.8 * payroll[i].payrate * (payroll[i].hours_worked - 40));
    }
    else
}

exists only to use ONE different constant multiplier. It can be reduced to:

Employee *e = payroll   i;
e->payment = e->hours_worked * e->payrate;
if (e->hours_worked > 40)
    e->payment  = (e->title == 'B') ? 0.5 : 0.8 * e->payrate * (e->hours_worked - 40);

Employees are paid their standard rate for all hours worked.
Overtime hours (above 40) are paid at the appropriate overtime rate.

Write less, but more effective, code.
The reader shouldn't be forced to scan large blocks of duplicate code trying to spot the tiny difference(s) between them.
(In fact, the calculation should be factored-out into a separate function, isolating that calculation from the "flow" of reading records and tabulating other values.)

CodePudding user response:

many many errors (your compiler should have warned you about at least some of them)

fscanf(infile, "%s", &payroll[i].name) )

do not pass a pointer to the string for %s , should be

fscanf(infile, "%s", payroll[i].name) )

use %c for a char , so this

fscanf(infile, "%s", &payroll[i].title);

should be

 fscanf(infile, " %c", &payroll[i].title);

notice the leading space to eat up the crlf in the buffer

fscanf(infile, "%s", &payroll[i].hours_worked);

you use %s here to say you want a string , but read it into a double, same on next like, should be

fscanf(infile, "%lf", &payroll[i].hours_worked);

here

 fprintf(outfile, "total: $%.2lf\n average: $%.2lf\nMAx: $%.2lf\n Min: $%.2lf", total, average, max, min);

you output ints using %lf, should be

 fprintf(outfile, "total: $%.2lf\n average: $%d\nMAx: $%d\n Min: $%d", total, average, max, min);

always test the return value of functions , especially io (fscanf)

also read this about while !eof

Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?

next, when readin a string using %s fscanf reads up to the first whitespace

so this

 if (fscanf(infile, "%s", payroll[i].name) == NULL)
        break;

when fed

Smith, Susan

(note the space after the ',') actually reads

"Smith,"

into the name

the next read (of a char) picks up 'S', and then the read of doubles tries to read 'mith', that wont work.

You should use fgets instead, that read the whole line

  if (fgets(payroll[i].name, 100, infile) == NULL)
        break;

note the change to correctly detect eof (I have while(1) for the loop)

also need to add fgetc(infile) after the last double read in order to eat up the cr lf before the next fgets

now get

 total: $1283.34
  average: $320
 MAx: $5360
  Min: $1283
  • Related