从char* 到char的转换无效

vxbzzdmp  于 2023-01-16  发布在  其他
关注(0)|答案(4)|浏览(244)

我确信这段代码会有比这更大的错误,但目前我得到的唯一错误是从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 any more? (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);
jyztefdp

jyztefdp1#

我认为你的函数签名是错误的。你可能需要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);
o2g1uqev

o2g1uqev2#

所以你要做的就是请求一个指向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);
pftdvrlh

pftdvrlh3#

抱歉,我没有识别垂直滚动条。您得到的错误是由于main中的fullName具有char *的类型,因为数组标签是指向元素序列的第一个元素的指针。
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个双精度型,但是你在PrintSummaryReport函数中第一次调用fprintf的时候就把一个额外的浮点数推给了它。
然后,定义为REPORTLINEFORMAT2" Totals %6.2f%11.2f%9.2f%9.2f%10.2f\n"将使第二个fprintf期望5个double,但您只将3个float推到它,比期望的少2个。
在函数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

一般而言,将所有这些改为:

*totRegHour = *totOvtHours = *totPayrate = *totGross = *totdeferred =
    *totFedtax = *totStatetax = *totSSItax = *totNet = *empCount = 0;

根据赋值运算符=的结合性方向,赋值将从右向左进行。因此,首先,0将被赋值给*empCount,它们将一起赋值给0。然后,0将被赋值给*totNet,依此类推......
现在,在main函数中,你显然已经用"wt"标志打开过"./report.txt"一次了。w标志将截断,也就是说,清除一个已经存在的同名文件的所有内容。根据你的需要,可以在那里这样做。
然而,一旦你在那里这样做,你不应该fopen ing同一个文件与"wt"标志一遍又一遍,否则的内容将被清除与每个fopen.因为你已经打开它一次在main中,你应该删除以下行:

reportFile = fopen( "./report.txt", "wt" );

来自函数PrintReportHeadingsPrintSummaryReport,否则文件将只包含上次调用fopen后放置的内容。
由于firstNamelastName的空间非常有限,您可能希望限制scanfInputEmployeeData函数中读取的字符数,如下所示:

...
scanf( "%10s", firstName );
...
scanf( "%15s", firstName );

这个宽度规范只考虑字符的数量,没有考虑所需的终止字符'\0',所以不要在那里写11和16。
此外,您可能希望将fullName的容量增加2,以便将介于两者之间的", "考虑在内。

eagi6jfj

eagi6jfj4#

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

相关问题