从char *到char的转换无效

时间:2014-03-29 10:49:15

标签: c

我确信此代码会出现更多错误,但是目前我遇到的唯一错误是从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, &regHours, &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);

感谢您的帮助,这个计划将成为我的死!

4 个答案:

答案 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后放置内容。

由于fopenfirstName的空间非常稀少,您可能希望限制lastNamescanf内的字符数量。功能,像这样:

InputEmployeeData

此宽度规范事项仅计算字符数,不考虑所需的终止... scanf( "%10s", firstName ); ... scanf( "%15s", firstName ); 。所以不要在那里写11和16。

此外,您可能希望将'\0'的容量增加2,以便将fullName考虑在内。

答案 3 :(得分:0)

unction定义中的fullname参数应为char fullname[]char* fullname