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
{
In开发者_如何学CputEmplData(&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
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.
精彩评论