1

I am writing a program in C. I am trying to learn the difference between pass by reference and pass by value. I'm not sure if I got those right.

I am getting a segmentation fault / core dump error after executing the do while loop for the second time. What am I missing with the loop?

Here is my main:

#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>

extern void CalculateTaxes(float gross,float defr, float *ft,float *st,float *ssit);
extern float calcGross(float hours, float payrate);
extern void InputEmplData(char *lastname, char *firstname, float *hours, float *payrate, float *defr);
extern void InitAcc(float *totreg, float *totovt, float *totrate, float *totgross, float *totfed, float *totstate, float *totssi, float *totdef,  float *totnet);
extern void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, float pr, float *totpayrate, float theGross, float *totgross,float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, float defr, float *totdef, float net, float *totnet);

int main(void)
{
   float fedtax,statetax,ssitax;
   float theGross;
   //int  counter=0;
   char answer;
   char lastname, firstname;
   float hours, payrate, defr, reghrs, ovthrs, net, numemps;
   float totgross, totpayrate, totreg, totovt, totrate, totfed, totstate, totssi, totdef, totnet;

/*
   FILE * reportFile; // 1) declare a FILE * variable

   reportFile = fopen("./report.txt","wt");
   // 2) open a report file with access mode "write-text"
   if (reportFile == NULL)
   {
     printf("  Report file open failed ...\n");
     fflush(stdin);
     getchar();
     exit(-10); // terminate w/ failure code -10; reqs <stdlib>
   }
*/
   printf("  Welcome to the Employee Tax Program\n");
   printf("  Please enter the number of employees taxes will be calculated:");
   scanf (" %f", numemps);
   InitAcc(&totreg, &totovt, &totrate, &totgross, &totfed, &totstate, &totssi, &totdef, &totnet);

   do 
   {
     InputEmplData(&lastname, &firstname, &hours, &payrate, &defr);   
     theGross = calcGross(hours, payrate); // call 3.4
     CalculateTaxes(theGross,defr,&fedtax,&statetax,&ssitax); // 3.5
     net=(theGross-defr)-fedtax-statetax-ssitax;
     AddDetail2Acc(reghrs, &totreg, ovthrs, &totovt, payrate, &totpayrate, theGross, &totgross,fedtax, &totfed, statetax, &totstate, ssitax, &totssi, defr, &totdef, net, &totnet);
     printf("    Fedtax    = %8.2f",fedtax);
     //fprintf(reportFile,"    Fedtax    = %8.2f",fedtax);
     //fprintf(stdout,"    Fedtax    = %8.2f",fedtax);
     printf("    Statetax  = %8.2f",statetax);
     //fprintf(reportFile,"    Statetax  = %8.2f",statetax);
     //fprintf(stdout,"    Statetax  = %8.2f",statetax);
     printf("    SSItax    = %8.2f\n",ssitax);
     //fprintf(reportFile,"    SSItax    = %8.2f\n",ssitax);
     //fprintf(stdout,"    SSItax    = %8.2f\n",ssitax);
     //printf(" %f %f %f %f %f %f %f %f", totreg, totovt, totrate, totfed, totstate, totssi, totdef, totnet);
     printf("  Do you have another employee(YES = 1 / No = 2) ==> ");
     fflush(stdin);
     scanf (" %c", answer);
     answer = getchar();
     getchar(); // removes '\n' from response

   } while (answer == 'y' || answer == 'y');

   //fclose(reportFile); // 4) close the file
   printf(" Press any key ... ");
   fflush(stdin);
   getchar();
   return 0;
}

Here are my functions:

#include <stdio.h>

void InputEmplData (char *lastname, char *firstname, float *hours, float *payrate, float *defr);

void InputEmplData (char *lastname, char *firstname, float *hours, float *payrate, float *defr)
{   
   printf("  Please enter your lastname: ");
   scanf (" %s", lastname);
   fflush(stdin);

   printf("  Please enter your firstname: ");
   scanf (" %s", firstname);
   fflush(stdin);

   printf("  Please enter the hours you have worked including overtime: ");
   scanf (" %f", hours);
   while (hours < 0)
   {
    printf(" Please enter a valid number. Must be between 0.");
    scanf (" %f", hours);
   }
   printf("  Please enter your payrate(15.00): ");
   scanf (" %f", payrate);
   while (payrate <= 0)
   {
    printf(" Please enter a valid number. Must be above 0.");
    scanf (" %f", payrate);
   }
   printf("  Please enter the amount exempt from taxes: ");
   scanf (" %f", defr);

   while (defr <= 0)
   {
    printf(" Please enter a valid number. Must be above 0.");
    scanf (" %f", defr);
   }
}

CalculateTaxes function:

#include "./taxrates.h" //user defined header for tax rates

void CalculateTaxes(float gross,float defr, float *ft,float *st,float *ssit);
float calcFed(float gross, float defr);
float calcState(float ft);
float calcSSI(float gross,float defr);

void CalculateTaxes(float gross,float defr, float *ft,float *st,float *ssit)
{
  *ft = calcFed(gross,defr);
  *st = calcState(*ft);
  *ssit = calcSSI(gross,defr);
}

float calcFed(float gross, float defr)
{
  return (gross-defr)*FEDTAXRATE;
}

float calcState(float ft)
{
  return ft * STATETAXRATE;
}

float calcSSI(float gross,float defr)
{
  return (gross-defr)*SSITAXRATE;
}


float calcGross(float h, float pr);

float calcGross(float h, float pr) 
{
  return h <= 40? h * pr : 40 *h + (h-40)*1.5*pr;
}

Function to initialize counters:

void InitAcc(float *totreg, float *totovt, float *totrate, float *totgross, float *totfed, float *totstate, float *totssi, float *totdef,  float *totnet);

void InitAcc(float *totreg, float *totovt, float *totrate, float *totgross, float *totfed, float *totstate, float *totssi, float *totdef, float *totnet)
{
  *totreg = 0;
  *totovt = 0;
  *totrate = 0;
  *totgross = 0;
  *totfed = 0;
  *totstate = 0;
  *totssi = 0;
  *totdef = 0;
  *totnet = 0;
}

Function to use counters (unfinished):

#include <stdio.h>

 void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, 
            float pr, float *totpayrate, float theGross, float *totgross,
            float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, 
            float defr, float *totdef, float net, float *totnet);

 void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, 
            float pr, float *totpayrate, float theGross, float *totgross,
            float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, 
            float defr, float *totdef, float net, float *totnet)
{
    *totgross+= theGross;
    *totreg += reghrs;
    *totovt += ovthrs;
    *totpayrate += pr;
    *totfed += ft;
    *totstate += st;
    *totssi += ssit;
    *totdef += defr;
    *totnet += net;

}

Makefile:

calc.obj:   calctaxes.cpp taxrates.h
    g++ -c calctaxes.cpp -o calc.obj

main2.exe:  main2.cpp calc.obj cGross.obj InputEmplData.obj InitAcc.obj
    g++ main2.cpp calc.obj cGross.obj InputEmplData.obj InitAcc.obj AddDetail2Acc.obj -o main2.exe

cGross.obj: calcGross.cpp InputEmplData.obj
    g++ -c calcGross.cpp -o cGross.obj

InputEmplData.obj:  InputEmplData.cpp
    g++ -c InputEmplData.cpp -o InputEmplData.obj

InitAcc.obj:    InitAcc.cpp InputEmplData.obj
    g++ -c InitAcc.cpp InputEmplData.obj -o InitAcc.obj

AddDetail2Acc.obj:  AddDetail2Acc.cpp
    g++ -c AddDetail2Acc.cpp InitAcc.obj -o AddDetail2Acc.obj
JoshDM
  • 4,939
  • 7
  • 43
  • 72
  • 1
    there's way too much code and way too little information about where the code is failing. please try and shorten it to a _small_ snippet that is correct and has the behavior. Doing that might actually help you solving this yourself. – Mat Apr 24 '11 at 08:56

1 Answers1

2

There is really a lot of code here, but here is the first error I see:

//...
extern void InputEmplData(char *lastname, char *firstname, float *hours, float *payrate, float *defr);
//...

    char lastname, firstname;

//...
    InputEmplData(&lastname, &firstname, &hours, &payrate, &defr);

//...
void InputEmplData (char *lastname, char *firstname, float *hours, float *payrate, float *defr)
{   
   printf("  Please enter your lastname: ");
   scanf (" %s", lastname);
   fflush(stdin);

   printf("  Please enter your firstname: ");
   scanf (" %s", firstname);
   fflush(stdin);

Unless you aren't assuming that lastname and firstname lengths is 1, then here is your first error. You are receiving segmentation fault because you are writing a string with lentgh of more then 1 into char.

Possible correction is to define:

char lastname[NAME_LENGTH], firstname[NAME_LENGTH];

/...
InputEmplData(lastname, firstname, &hours, &payrate, &defr);

With this you will achieve desired effect. I used arrays of char for lastname and firstname, but you can allocate memory for lastname and etc dynamically with malloc, but I wouldn't recommend you to do this without clear understanding of what you are doing.

Also, I have just several small advices, not considering segmentation fault:

1.Try to create some structures, that would represent different groups of variables. Then you can write, for example, instead of

void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, 
            float pr, float *totpayrate, float theGross, float *totgross,
            float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, 
            float defr, float *totdef, float net, float *totnet);

something like this:

void AddDetail2Acc(AccStruct *in_out_sourceAcc, AddDataStruct in_addData);

This is more readable and less error prone.

2.As I understand from variables name you are performing some operations with money values. Try not to use float variables to represent money value. Floating point arithmetic one day can give you a small suprise. Try to use integer types.

beduin
  • 7,943
  • 3
  • 27
  • 24
  • I'm away from my computer at the moment, but when I set an array for the (string) names I get another error that I will post when I get to my computer. I will try again when I get home. I posted all the code because I had no idea what the issue could have been. After I get the base program complete I will be implementing a struct and an array to the whole program. Its sort of a two part assignment. I guess I could use integers, but I thought when you have any decimal numbers that you should use doubles or floats? – CowboyBebopFan Apr 25 '11 at 00:54
  • Sure, post your error. Considering floatin point operations - you can read [this](http://stackoverflow.com/questions/273371/real-vs-floating-point-vs-money) discussion. – beduin Apr 25 '11 at 04:28
  • I tried to add an array for the strings and I still get a segmentation fault, but I think that the fault issue with something different. I was adding a line to ask the user for the number of employees but once I enter any number I get a seg fault error so I removed it. `printf(" Please enter the number of employees taxes will be calculated:"); scanf (" %f", numemps);` Sorry I keep posting. So far the seg faults are all the errors I get. – CowboyBebopFan Apr 25 '11 at 05:54
  • This is quite simple. You have to provide scanf with variable _address_. It means you should write `scanf("%f", &numemps)`. Check example [here](http://www.cplusplus.com/reference/clibrary/cstdio/scanf/). It shows how to use scanf to input integral types. – beduin Apr 25 '11 at 07:48
  • Beduin thank you. I'm rewriting this code is C++ because I know it better. I can tell know I need review C again. Don't worry I'll be back. Thanks again. – CowboyBebopFan Apr 25 '11 at 08:19