-1

I am working on an employee pay program in C and I am trying to find a better way of organizing the code for calculating the pay for the Hourly Worker. I want to use a switch statement, instead of a boatload of if statements. I was just wondering if that was possible? Would the cases need a value or can it stay blank? For example, could I use just "case:" instead of "case value1:"? I know that if I do use a switch statement that I will probably have to use if's to validate that what the user put in is valid. Or should I just stick with a bunch of if's?

In case you were wondering, here are the directions that I need to follow:

  1. A company pays its employees as: a) managers, who receive a fixed weekly salary; b) hourly workers, who receive a fixed hourly wage for up to the first 40 hours they work and "time-and-a-half", i.e. 1.5 times their hourly wage for overtime hours; c) commission workers, who receive $250 plus 5.7% of their weekly sales; or d) pieceworkers, who receive a fixed amount per item for each item produced.

Write a program to compute weekly pay for each employee. You don’t know the number of employees in advance. Each employee type has their own pay code:

1 for Managers
2 for Hourly Workers
3 for Commission Workers
4 for Pieceworkers.

Write a separate function to handle each paycode type. Use a switch to compute each employee's pay based on that employee's paycode. Within the switch, prompt the user to enter the appropriate facts the program needs to calculate each employee's pay based on that employee's paycode.
Add reasonableness checks as appropriate (e.g., salary between 0 - 100000, hours worked between 0 – 84, hourly rate between 0 – 250, weekly sales between 0 – 1000000, number of pieces between 1 – 1000, wage per piece between 0.01 – 1000. Use constants).

Here are the program constants: #include

//  constants
#define MANAGERS                1
#define HOURLY_WORKERS          2
#define COMMISSION_WORKERS      3
#define PIECEWORKERS            4
#define STOP_PROGRAM            -1
#define COMMISSION_PERCENT      0.057
#define COMMISSION_PAY          250
#define OVERTIME_HOURS          1.5
#define MAX_HOURS_WORKED        40

Here is the code I have so far for the Hourly Worker function:

void calcHourlyWorkerPay()
{
    float hourlyPayRate;
    int totalHoursWorked;
    float totalPay;

    printf("You entered 2 for Hourly Worker.\n\n");
    printf("Enter hourly pay rate.\n" 
        "(Entry must be between 0 and 250): ");
    scanf  ("%f", &hourlyPayRate);
    printf("Enter total hours worked.\n" 
        "(Entry must be between 0 and 84): ");
    scanf  ("%d", &totalHoursWorked);

    if ((totalHoursWorked <= MAX_HOURS_WORKED) && (totalHoursWorked >= 84))
    {

    }
}

The reason I am asking is because I want to add validation to this where if the user enters a number that is not between 0 and 84, it will say something like "Entry invalid, please enter a number between 0 and 84." I also want to add validation where if the user enters an hourly rate that is not between 0 and 250, it will say something like "Entry invalid, please enter a number between 0 and 250." I hope I didn't confuse anyone. I probably made a few mistakes, and I should point out that I am VERY new to C programming.

EDITED

I edited the if statement as follows:

if (((totalHoursWorked >= 0) && (totalHoursWorked <= 84)) && ((hourlyPayRate >= 0) && (hourlyPayRate <= 250)))
{
    totalPay = totalHoursWorked * hourlyPayRate;
}
else if ((totalHoursWorked <= 0) || (totalHoursWorked >= 84))
{
    printf("\n\nINVALID!!!  Total hours worked MUST be between 0 and 84.\n\n");
    printf("Enter total hours worked.\n" 
        "(Entry must be between 0 and 84): ");
    scanf  ("%d", &totalHoursWorked);

}
else if ((hourlyPayRate <= 0) || (hourlyPayRate >= 250))
{
    printf("\n\nINVALID!!!  Hourly pay rate MUST be between 0 and 250.\n\n");
    printf("Enter hourly pay rate.\n" 
        "(Entry must be between 0 and 250): ");
    scanf  ("%f", &hourlyPayRate);
}
else
{
    totalPay = (MAX_HOURS_WORKED * hourlyPayRate) + ((hoursWorked - MAX_HOURS_WORKED) * hourlyPayRate * OVERTIME_HOURS);
}

Is that correct and will it work?

  • 1
    You'd probably need to give an example of what a boatload of if statements looks like. Case values in switches are required except for the default case if no other case matches. It seems reasonable to use a switch for the employee type and just call a function to do the calculations and such from there. – Retired Ninja Sep 27 '14 at 23:57
  • That's what the calcHourlyWorkerPay function is supposed to do. It's supposed to do the calculations for the Hourly Worker. I didn't post my entire code on here (that would be more helpful) because I already got yelled at for it. – InSeriousNeedOfAspirin Sep 28 '14 at 00:02
  • I cannot see any nested `if` statements in your code and except for the employee types, I cannot see where you could use a `switch` statement. But a stylistic remark: Get rid of your `#define`s. Make the employee types an `enum` and add global `static const`ants for the other constants. – 5gon12eder Sep 28 '14 at 00:45
  • 1) Calculations such as `totalPay = totalHoursWorked * hourlyPayRate;` should be rounded to the nearest cent. e.g. `totalPay = round(totalHoursWorked * hourlyPayRate *100)/100;` 2) "Is that correct and will it work?" is vague. Provide specific questions to get specific answers. – chux - Reinstate Monica Sep 28 '14 at 00:48
  • 1) After each user input, qualify the data `printf("Enter ..."); int count = scanf ("%f", &hourlyPayRate); if (count != 1 || hourlyPayRate < 0.0 || hourlyPayRate > COMMISSION_PAY) HandleError();` 2) Recommend to use `double` and not `float`. – chux - Reinstate Monica Sep 28 '14 at 00:52
  • @chux I forgot to add this: printf ("Hourly Worker's pay:\t\t\t\t$%.2f", totalPay); return; At the very end after the very last ending bracket of the if statement. I think it does the rounding that you are talking about. – InSeriousNeedOfAspirin Sep 28 '14 at 00:53
  • It presents a rounded version for printing. It does not round the variable `totalPay` and that should to be rounded for subsequent calculations and consistency. – chux - Reinstate Monica Sep 28 '14 at 00:55
  • @chux Do you have a good reason to suggest why double should be used instead of float? How is 32-bit floating-point precision not infinitely more than sufficient for such a basic task with extremely few operations, limited range, and a result that requires extremely low precision? If you're really concerned about precision in terms of finances, fixed point/BCD should be used. If this is coming from a numerical accuracy perspective, why are the comparisons you're using not taking epsilon into account? –  Sep 28 '14 at 01:04
  • @Sanhadrin 1) C defaults to `double` for so many things like `#define COMMISSION_PERCENT 0.057` used in `if (x > COMMISSION_PERCENT) ...` and all `printf()` of floating point. For a learner to write code using `float` and `double` often falls into various precision issues of the 2. 2) It is not for the extra range and precision I suggest `double`, it is for the _consistency_ of using only 1 floating point type. 3) `float` and money invariable is too limited. OP is taking about money in the $100,000 range and that is 7 digits of `cents` exceeding typical `float`. – chux - Reinstate Monica Sep 28 '14 at 01:14
  • @Sanhadrin I can answer the first question, it's because our instructor told us to use float for currency and double for other numbers containing decimals. As for the last question, I have no clue what you mean. – InSeriousNeedOfAspirin Sep 28 '14 at 01:15
  • @Sanhadrin If `double` is used for user input and range are also `double` and not calculation has not occurred, epsilon is not needed. But in general, factor some epsilon is a good idea, but likely more than what OP can handle at this point. – chux - Reinstate Monica Sep 28 '14 at 01:17
  • @chex 1) I'm not sure what "and range are also double" means, but the scanf code and the type have to match for the value to be represented correctly. More importantly, it's 100% possible to input a decimal value that exceeds the precision of any floating point type, as per the standard and even a simple test, which means that the value may be rounded and thus epsilon would still need to be used. 2) This contradicts your (3) - you're saying the significant digits exceed that of float, therefore double's extended range and precision will give more correct value. –  Sep 28 '14 at 02:02
  • 3) If for consistency, your earlier validation code should suffix the float literals with 'F' as it was comparing float vs. double. There's no practical issue with it since the float would be upcast, but that's the point - there's no practical problem with his existing usage of floating point either, and saying "use double" early on is what gives 99% of them the wrong idea that they must "always use double". Beyond that, the nature of floating-point calculations of any precision are a problem in financial calculations, not just 32-bit. –  Sep 28 '14 at 02:04

1 Answers1

0

For one, you're checking if (totalHoursWorked >= 0) in one expression, and (totalHoursWorked <= 0) in the "else" condition. A check against equality with zero should only exist in one of those checks. You should also factor out the common expressions to simplify them - for example, you already check if values like totalHoursWorked are within bounds in one condition, but you're re-checking it further down if the expression evaluates to false because you've overcomplicated it by combining it with the check for hourlyPayRate. If you need to know if an expression involving a variable failed, you should make that the only variable in that expression, and save the sanity checks for other values until the first check passes.

It also isn't clear what happens if a value is out of range on the re-entry try. If it fails, it asks you to re-enter the value, but it won't be checked again. You need to put the entry and validation logic in a construct that will repeat until the value is within range (or they indicate they want to quit) no matter how many times they enter invalid values.

Since there's a focus on using constants, the values you're using for your validation checks should also be constant.