我确信此代码会出现更多错误,但是目前我遇到的唯一错误是从char *到char的无效转换
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define REPORTHEADING1 " Employee Pay Hours Gross Tax Net\n"
#define REPORTHEADING2 " Name Rate Worked Pay Due Pay\n"
#define REPORTHEADING3 " =============== ==== ====== ===== ==== ====\n"
#define REPORTHEADING4 " ==== ====== ===== ==== ====\n"
#define REPORTLINEFORMAT1 " %-20s%6.2f%11.2f%9.2f%9.2f%10.2f\n"
#define REPORTLINEFORMAT2 " Totals %6.2f%11.2f%9.2f%9.2f%10.2f\n"
#define REPORTLINEFORMAT3 " Averages %6.2f%11.2f%9.2f%9.2f%10.2f\n"
#define COUNTLINEFORMAT " Number of employees: %-10i\n\n"
#define MAXREGHOURS 40
#define OVERTIMERATE 1.5
void PrintReportHeadings(FILE *reportFile); //printReportHeadings prototype
void InitializeAccumulators(float *totRegHour,float *totOvtHours,float *totPayrate,
float *totGross,float *totdeferred,float *totFedtax,
float *totStatetax,float *totSSItax,float *totNet,int *empCount); //InitializeAccumulators prototype
void InputEmployeeData(char *firstName,char *lastName,
float *hours,float *payrate,float *deferred); //InputEmployeeData prototype
void CalculateGross(float hours,float payrate,float *regHours,float *ovtHours,
float *gross); //CalculateGross prototype
extern void CalculateTaxes(float gross,float deferred,float * fedtax,
float * statetax,float * ssitax); //CalculateTaxes prototype (external)
float CalculateNetPay(float gross,float fedtax,float statetax,float ssitax,
float deferred);
void AddDetailToAccumulators(float regHours,float ovtHours,float payrate,
float gross,float deferred,float fedtax,float statetax,
float ssitax,float net,float *totRegHours,float *totOvtHours,
float *totPayrate,float *totGross,float *totdeferred,
float *totFedtax,float *totStatetax,float *totSSItax,
float *totNet);
void PrintSummaryReport(FILE *reportFile,char fullName,float regHours,float ovtHours,
float payrate,float gross,float deferred,float fedtax,
float statetax,float ssitax,float net);
int main(void)
{
float ft,st,ssit;
char firstName[10+1];
char lastName[15+1];
char fullName[25+1];
float regHours, ovtHours, hours, payrate, deferred, gross, netpay;
float totRegHours, totOvtHours, totPayrate, totGross,totdeferred,
totFedtax, totStatetax, totSSItax, totNet;
int empcount;
char answer;
FILE * reportFile;
reportFile = fopen("./report.txt","wt");
if(reportFile == NULL)
{
printf(" Report open request failed...\n");
while(getchar() != '\n');
exit(-90);// reqs <stdlib.h>
}
PrintReportHeadings(reportFile);
InitializeAccumulators(&totRegHours,&totOvtHours,&totPayrate,&totGross,
&totdeferred,&totFedtax,&totStatetax,&totSSItax,&totNet,
&empcount);//set all accumulators to 0
do
{
InputEmployeeData(firstName,lastName,&hours,&payrate,&deferred);
CalculateGross(hours, payrate, ®Hours, &ovtHours, &gross);
CalculateTaxes(gross,deferred,&ft,&st,&ssit);
netpay = CalculateNetPay(gross,ft,st,ssit,deferred);
strcpy(fullName,lastName);
strcat(fullName,", ");
strcat(fullName,firstName);
AddDetailToAccumulators(regHours,ovtHours,payrate,gross,deferred,ft,st,
ssit,netpay,&totRegHours,&totOvtHours,&totPayrate,&totGross,
&totdeferred,&totFedtax,&totStatetax,&totSSItax,&totNet);
PrintSummaryReport(reportFile,fullName,regHours,ovtHours,payrate,gross,deferred,ft,st,ssit,netpay);
empcount++;
printf(COUNTLINEFORMAT,empcount);
printf(" do you have anymore? (Y/N): ");
while(getchar() != '\n');
answer = getchar();
printf("\n");
}
while(answer != 'N' && answer != 'n');
while (getchar()!= '\n');
getchar();
return 0;
}
void PrintReportHeadings(FILE *reportFile)
{
reportFile = fopen("./report.txt","wt");
fprintf(reportFile,REPORTHEADING1);
fprintf(reportFile,REPORTHEADING2);
fprintf(reportFile,REPORTHEADING3);
}
void InitializeAccumulators(float *totRegHour,float *totOvtHours,float *totPayrate,
float *totGross,float *totdeferred,float *totFedtax,
float *totStatetax,float *totSSItax,float *totNet,int *empCount)
{
totRegHour, totOvtHours, totPayrate, totGross,totdeferred,
totFedtax, totStatetax, totSSItax, totNet, empCount = 0;
}
void InputEmployeeData(char *firstName,char *lastName,float *hours,
float *payrate,float *deferred)
{
printf(" Enter employee first name : ");
scanf("%s",firstName);
printf(" Enter employee last name : ");
scanf("%s",lastName);
printf(" Enter %s's hours worked : ",firstName);
scanf("%f",hours);
printf(" Enter %s's pay rate : ",firstName);
scanf("%f",payrate);
printf(" Enter %s's amount deferred : ",firstName);
scanf("%f",deferred);
}
void CalculateGross(float hours,float payrate,float *regHours,float *ovtHours,float *gross)
{
float overtimeHours(float hours);
if(hours <= MAXREGHOURS)
{
*regHours = hours;
*gross = hours * payrate;
}
else
{
*regHours = MAXREGHOURS;
*ovtHours = overtimeHours(hours);
*gross = payrate * MAXREGHOURS + OVERTIMERATE * payrate * (hours - MAXREGHOURS);
}
}
float overtimeHours(float hours)
{
return hours - MAXREGHOURS;
}
float CalculateNetPay(float gross,float fedtax,float statetax,float ssitax,
float deferred)
{
return gross - (fedtax + statetax + ssitax + deferred);
}
void AddDetailtoAccumulators(float regHours,float ovtHours,float payrate,
float gross,float deferred,float fedtax,float statetax,
float ssitax,float netpay,float *totRegHours,float *totOvtHours,
float *totPayrate,float *totGross,float *totDeferred,
float *totFedtax,float *totStatetax,float *totSSItax,
float *totNet)
{
*totRegHours =+ regHours;
*totOvtHours =+ ovtHours;
*totPayrate =+ payrate;
*totGross =+ gross;
*totDeferred =+ deferred;
*totFedtax =+ fedtax;
*totStatetax =+ statetax;
*totSSItax =+ ssitax;
*totNet =+ netpay;
}
void PrintSummaryReport(FILE *reportFile,char fullName,float regHours,float ovtHours,
float payrate,float gross,float deferred,float fedtax,
float statetax,float ssitax,float netpay)
{
reportFile = fopen("./report.txt","wt");
fprintf(reportFile,REPORTLINEFORMAT1,fullName,payrate,regHours,gross,fedtax,
ssitax,netpay);
fprintf(reportFile,REPORTLINEFORMAT2,ovtHours,statetax,deferred);
}
发生错误的行:
PrintSummaryReport(reportFile,fullName,regHours,ovtHours,payrate,gross,deferred,ft,st,ssit,netpay);
感谢您的帮助,这个计划将成为我的死!
答案 0 :(得分:2)
我认为你的功能签名是错误的。您可能需要char * fullname
而不是char fullname
。
void PrintSummaryReport(FILE *reportFile,char /* you probably want this to be a char * */ fullName,float regHours,float ovtHours,
float payrate,float gross,float deferred,float fedtax,
float statetax,float ssitax,float net);
答案 1 :(得分:1)
所以你正在做的是要求指向reportFile的指针,并且你正在为它提供其他东西。
void PrintSummaryReport(FILE *reportFile,char fullName,float regHours,float ovtHours,
float payrate,float gross,float deferred,float fedtax,
float statetax,float ssitax,float net);
printSummaryReport(reportFile,fullName,regHours,ovtHours,payrate,gross,deferred,ft,st,ssit,netpay);
我认为这样可以正常工作:
printSummaryReport(&reportFile,fullName,regHours,ovtHours,payrate,gross,deferred,ft,st,ssit,netpay);
答案 2 :(得分:1)
抱歉,我无法识别垂直滚动条。您得到的错误是由于fullName
内的main
具有char *
类型的事实,因为数组标签是指向元素序列的第一个元素的指针。 / p>
fullName[0]
或*(fullName + 0)
两者都相同且都是char
,但fullName
仅为char *
。
此外,%s
格式说明符或您使用的%-20s
,无论如何都期望指向字符char *
的指针。但是,您正在尝试为其添加字符char
。进行以下更改以解决我上面所述的所有事情:
// prototype
void PrintSummaryReport( FILE *reportFile, char * fullName, // <-- added an asterisk *
float regHours, float ovtHours, float payrate, // after char
float gross, float deferred, float fedtax,
float statetax, float ssitax, float net );
...
// definition
void PrintSummaryReport( FILE *reportFile, char * fullName, // <-- same here
float regHours, float ovtHours, float payrate,
float gross, float deferred, float fedtax,
float statetax, float ssitax, float netpay ) { ... }
您的代码中还有一些问题。例如,定义为" %-20s%6.2f%11.2f%9.2f%9.2f%10.2f\n"
的格式字符串REPORTLINEFORMAT1
有1个字符串和5个双打,但是您在fprintf
内的第一个PrintSummaryReport
调用中向其推送了1个额外的浮点数功能
然后定义为" Totals %6.2f%11.2f%9.2f%9.2f%10.2f\n"
的{{1}}会使第二REPORTLINEFORMAT2
期望5个双倍,但你只推动3个浮点数,比预期的少2个。
在函数fprintf
内,所有AddDetailtoAccumulators
都是奇怪的表示法。前面的+在那里没有做任何事情,可能不会在C中的任何地方做任何事情,甚至在C ++中它可能在浮动后面。确保您不想要添加分配= +
运算符。
+=
函数中有一个有趣的原型:
CalculateGross
它做了它应该做的事情,原型化一个将在某些更多行中定义的函数,允许您在定义之前正确使用它。由于该函数float overtimeHours( float hours );
仅在overtimeHours
内使用,因此它可以正常使用,但将它置于最顶端仍然更为明智。在CalculateGross
函数之外,您将无法在其定义之上的任何位置使用overtimeHours
。
CalculateGross
内部出现了一些问题。我想你希望为这些指针所指向的所有变量分配一个零。逗号运算符InitializeAccumulators
无法帮助您。你可以做一个连锁任务;但首先,不要分配这样的指针,而是指定它指向的值:
,
一般来说,用以下内容替换所有内容:
// do it like
*empCount = 0;
// not like
empCount = 0;
// which would only invalidate the pointer, make the pointer point to the memory
// location that has the address of 0, I don't think you'd want that
根据此C Operator Precedence Table的赋值运算符*totRegHour = *totOvtHours = *totPayrate = *totGross = *totdeferred =
*totFedtax = *totStatetax = *totSSItax = *totNet = *empCount = 0;
的关联方向,评估将从右到左进行。因此,首先,=
将被分配到0
,这将完全评估为*empCount
。然后,0
将被分配到0
,依此类推......
现在,在*totNet
函数中,您显然已使用main
标记打开"./report.txt"
一次。 "wt"
标志将截断,即清除已存在的具有相同名称的文件的所有内容。根据你的需要,可以在那里做到。
但是,一旦你那样做,你就不应该w
反复使用fopen
标记的同一个文件,否则每个"wt"
都会清除内容。由于您已在fopen
中打开一次,因此应删除以下行:
main
从功能reportFile = fopen( "./report.txt", "wt" );
和PrintReportHeadings
开始,否则文件只会在最后一次调用PrintSummaryReport
后放置内容。
由于fopen
和firstName
的空间非常稀少,您可能希望限制lastName
内scanf
内的字符数量。功能,像这样:
InputEmployeeData
此宽度规范事项仅计算字符数,不考虑所需的终止...
scanf( "%10s", firstName );
...
scanf( "%15s", firstName );
。所以不要在那里写11和16。
此外,您可能希望将'\0'
的容量增加2,以便将fullName
考虑在内。
答案 3 :(得分:0)
unction定义中的fullname
参数应为char fullname[]
或char* fullname
。