编译器错误退出状态1

时间:2015-12-03 21:16:06

标签: c function compiler-errors

g++ -Wall -o "3bV2" "3bV2.cpp" (in directory: /home/dylan/Desktop/3b/Done)
/tmp/ccA8cFDY.o: In function `main':
3bV2.cpp:(.text+0x9ca): undefined reference to `struct_cmp_by_product(void const*, void const*)'
collect2: error: ld returned 1 exit status
Compilation failed.

编译时出现此错误。注意:它工作正常,直到我将我的功能外部化。

的main.cpp

#include <stdio.h>
#include <string.h> //reqd for strncat
#include <stdlib.h> // reqd for exit()
#include "./TAXRATES.h"
#include "./EmployeeRecord.h"
#define HEADERLINE1 "       Employee's             Pay      RegHours    Gross    Fed      SSI     Net\n"
#define HEADERLINE2 "       Name                   Rate     OvtHours    Worked   State    Defr\n"
#define HEADERLINE3 "       *******************    *****    ********    *******  ******   ******  ******\n"
#define REPLNEFORMT1 "       %-22s%6.2f%12.2f%10.2f%8.2f%8.2f%10.2f\n"//Main Header Line 1 (Thank you Dixon)
#define REPLNEFORMT2 "       %40.2f%18.2f%8.2f\n\n"//Main Header Line 2 (Thank you Dixon)
#define REPLNEFORMT3 "       %-21s%7.2f%12.2f%10.2f%8.2f%8.2f%10.2f\n"//Totals Line 1
#define MAX_SIZE 5

void EmptyFileError(void);//3.01
void InitializeAccumulators(float *totreg, float *totovt,float *totpayrate, float                           
                            *totgross, float *totfed, float *totstate, float *totssi, float                     
                            *totdefr, float *totnet); //3.02
void PrintReportHeadings(FILE * reportfile); //3.03
void NumberOfEmployees(int *NumEmployees); //3.04
void InputEmployeeData(char Ln[],char Fn[], float *Hours,float *Payrate, float               
                        *defr, float *ovt); // 3.05
float CalculateGross(float Hours,float Payrate);//3.06
void computeTaxes(float g,float d,float * fed,float *state,float *ssi); //3.07
void PrintUserData(float p,float Hours,float g,float fed,float ssi,float n,char str1[30],float ovt, 
                    float state,float d, FILE *reportfile);//3.09
void AddDetailToAccumulators(float *totpayrate, float p, float Hours, float *totreg,
                    float g, float *totgross, float fed, float *totfed, float ssi,                  
                    float *totssi, float n, float *totnet,
                    float *totovt,float  ovt, float state, float *totstate, float                   
                    defr, float *totdefr);//3.10
void CalcAverage(float totpayrate, float *avgtotpayrate,float totreg, float          
                *avgtotreg,float totgross, float *avgtotgross, float *avgtotfed, float totfed,
                float *avgtotssi, float totssi, float *avgtotnet, float totnet,
                float *avgtotovt, float totovt, float *avgtotstate, float totstate,
                float *avgtotdefr, float totdefr);//3.11
void PrintSummaryReport(float totpayrate, float totreg, float totgross,float totfed,
                        float totssi, float totnet, float totovt,float totstate,float                       
                        totdefr,float avgtotpayrate,float avgtotreg,float avgtotgross,float                 
                        avgtotfed, float avgtotssi,float avgtotnet,float avgtotovt,float                
                        avgtotstate,float avgtotdefr, FILE *reportfile);//3.12
void CalculateOT(float *Hours, float *ovt);//*3..11
void computeTaxes(float g,float d,float * fed,float *state,float *ssi); //3.07
float cFed(float g,float d); // 3.8.1
float cState(float ft); // 3.8.2
float cSSI(float g,float d); // 3.8.3
extern int struct_cmp_by_product(const void *a, const void *b);
void computeTaxes(float g,float d,float * ft,float *st,float *ssit)
{ // 3.5
   *ft = cFed(g,d); //  vs ft = cFed(g,d)
   *st = cState(*ft); // call 3.5.2
   *ssit = cSSI(g,d); // call 3.5.3
}   
float cFed(float g,float d) // 3.5.1
{
      return (g-d) * FEDTAXRATE;
}      
float cState(float ft) // 3.5.2
{
      return ft * STATETAXRATE;
}   
float cSSI(float g,float d) // 3.5.3
{
      return (g-d) * SSITAXRATE;
}

int main(void)
{
    EmployeeRecord MyAssociate[MAX_SIZE];
    float totpayrate, totreg, totovt, totgross, totfed, totstate, totssi,                   
            totdefr,totnet,avgtotpayrate,avgtotreg, avgtotgross,avgtotfed,
            avgtotssi, avgtotnet, avgtotovt, avgtotstate, avgtotdefr,                           
            ovt;
    // step 1: declare a report "file" variable
    FILE * reportfile;
    reportfile = fopen("./report.txt","wt");
    // step 2: open the "file" for "write-text" access
    if (reportfile == NULL)
    {
        EmptyFileError();
    }
    InitializeAccumulators(&totpayrate,&totreg,&totovt,&totgross,&totfed,&totstate,
                            &totssi,&totdefr,&totnet);
    PrintReportHeadings(reportfile);
    for (int EmpCounter = 0; EmpCounter < MAX_SIZE; EmpCounter++)
    {
        InputEmployeeData(MyAssociate[EmpCounter].Lastname,MyAssociate[EmpCounter].Firstname,&MyAssociate[EmpCounter].Hours,&MyAssociate[EmpCounter].Payrate,&MyAssociate[EmpCounter].Defr,&ovt);// call 3.3
        strcpy(MyAssociate[EmpCounter].FullName, MyAssociate[EmpCounter].Lastname);
        strcat(MyAssociate[EmpCounter].FullName, ", ");
        strcat(MyAssociate[EmpCounter].FullName, MyAssociate[EmpCounter].Firstname);
        CalculateOT(&MyAssociate[EmpCounter].Hours, &ovt);
        MyAssociate[EmpCounter].Gross =  CalculateGross(MyAssociate[EmpCounter].Hours,MyAssociate[EmpCounter].Payrate); // call 3.4
        computeTaxes(MyAssociate[EmpCounter].Gross,MyAssociate[EmpCounter].Defr,&MyAssociate[EmpCounter].FedTax,&MyAssociate[EmpCounter].StateTax,&MyAssociate[EmpCounter].SsiTax); // call 3.5
        MyAssociate[EmpCounter].NetPay = MyAssociate[EmpCounter].Gross-MyAssociate[EmpCounter].FedTax-MyAssociate[EmpCounter].StateTax-MyAssociate[EmpCounter].SsiTax-MyAssociate[EmpCounter].Defr;
        PrintUserData(MyAssociate[EmpCounter].Payrate,MyAssociate[EmpCounter].Hours,MyAssociate[EmpCounter].Gross,
            MyAssociate[EmpCounter].FedTax,MyAssociate[EmpCounter].SsiTax,MyAssociate[EmpCounter].NetPay,MyAssociate[EmpCounter].FullName,ovt,
            MyAssociate[EmpCounter].StateTax,MyAssociate[EmpCounter].Defr,reportfile);
        AddDetailToAccumulators(&totpayrate, MyAssociate[EmpCounter].Payrate, MyAssociate[EmpCounter].Hours, &totreg,
                         MyAssociate[EmpCounter].Gross, &totgross, MyAssociate[EmpCounter].FedTax, &totfed, MyAssociate[EmpCounter].SsiTax, &totssi, MyAssociate[EmpCounter].NetPay, &totnet,                        
                         &totovt, ovt, MyAssociate[EmpCounter].StateTax, &totstate, MyAssociate[EmpCounter].Defr, &totdefr);
          while(getchar() != '\n'); // flush(stdin)
    }  
    CalcAverage(totpayrate, &avgtotpayrate,totreg,&avgtotreg, totgross,                 
                &avgtotgross, &avgtotfed, totfed, &avgtotssi, totssi,&avgtotnet, totnet,            
                &avgtotovt, totovt, &avgtotstate, totstate,&avgtotdefr, totdefr);
    qsort(MyAssociate, MAX_SIZE, sizeof(struct EmployeeRecord), struct_cmp_by_product);//sort
    fclose(reportfile); // step 4: close the report file
    getchar();
    while (getchar() != '\n');
    return 0;
}
void EmptyFileError(void) //3.01
{
      printf(" Report file open failed ...\n");
      printf("   Press key to exit ...\n");
      while (getchar() != '\n'); // same as fflush(stdin)
      exit(-10); // reqs <stdlib.h>
}
void InitializeAccumulators(float *totpayrate, float *totreg,float *totovt,float                            
                            *totgross,float *totfed,float *totstate,
                            float *totssi, float *totdefr, float *totnet) //3.02
{
    *totpayrate = 0;
    *totreg = 0;
    *totovt = 0;
    *totgross = 0;
    *totfed = 0;
    *totstate = 0;
    *totssi = 0;
    *totdefr = 0;
    *totnet = 0;
}
void PrintReportHeadings(FILE * reportfile)//3.03
{
    fprintf(stdout,HEADERLINE1);
    fprintf(stdout,HEADERLINE2);
    fprintf(stdout,HEADERLINE3);
    fprintf(reportfile,HEADERLINE1);
    fprintf(reportfile,HEADERLINE2);
    fprintf(reportfile,HEADERLINE3);
}
void InputEmployeeData(char Ln[],char Fn[],
                       float Hours[],float *Payrate, float *defr, float *ovt)//3.05
{
    printf(" Enter the name ==> ");
    scanf("%s%s",Fn,Ln);
    printf(" Enter the hours and payrate ==> ");
    scanf("%f%f",Hours,Payrate);
    printf("  Enter the deferred earning amount ==> ");
    scanf("%f",defr);
}
void CalculateOT(float *Hours, float *ovt)//3.06 FLOWCHART!!!!
{
    if (*Hours > 40){
         *ovt = *Hours - 40;
         *Hours = *Hours - *ovt;
         }
    else
    {
        *ovt = 0.00;
     }
}
float CalculateGross(float Hours,float Payrate)//3.7
{
  if (Hours <= 40)
    return Hours * Payrate;
  else
    return 40* Payrate + 1.5 * Payrate * (Hours-40);
}
void PrintUserData(float p,float h,float g,float fed,float ssi,float n,char str1[30],
                 float ovt, float state,float d,FILE * reportfile)//3.09
{
        fprintf(stdout,REPLNEFORMT1,str1,p,h<=40?h:40,g,fed,ssi,n);  
        fprintf(stdout,REPLNEFORMT2,ovt,state,d);
        fprintf(reportfile,REPLNEFORMT1,str1,p,h<=40?h:40,g,fed,ssi,n);  
        fprintf(reportfile,REPLNEFORMT2,ovt,state,d);
}
void AddDetailToAccumulators(float *totpayrate, float p, float h, float *totreg,
                    float g, float *totgross, float fed, float *totfed, float ssi,                  
                    float *totssi, float n, float *totnet, float *totovt,
                    float ovt, float state, float *totstate, float defr, float *totdefr)//3.10
{   
    *totpayrate = p + *totpayrate;
    *totreg = h + *totreg;
    *totgross = g + *totgross;
    *totfed = fed + *totfed;
    *totssi = ssi + *totssi;
    *totnet = n + *totnet;
    *totovt = ovt + *totovt;
    *totstate = state + *totstate;
    *totdefr = defr + *totdefr;
}
void CalcAverage(float totpayrate, float *avgtotpayrate, float totreg, float *avgtotreg, float totgross, float *avgtotgross, float *avgtotfed, float            totfed, float *avgtotssi, float totssi,float *avgtotnet, float totnet,
            float *avgtotovt, float totovt, float *avgtotstate, float totstate, float *avgtotdefr, float totdefr)//3.11
{
    *avgtotpayrate = totpayrate / MAX_SIZE;
    *avgtotreg = totreg / MAX_SIZE;
    *avgtotgross = totgross / MAX_SIZE;
    *avgtotfed = totfed / MAX_SIZE;
    *avgtotssi = totssi / MAX_SIZE;
    *avgtotnet = totnet / MAX_SIZE;
    *avgtotovt = totovt / MAX_SIZE;
    *avgtotstate = totstate / MAX_SIZE;
    *avgtotdefr = totdefr / MAX_SIZE;
}

Qsort.cpp

#include <stdio.h>
#include "./EmployeeRecord.h"
#include <string.h> 
#define REPLNEFORMT1 "       %-22s%6.2f%12.2f%10.2f%8.2f%8.2f%10.2f\n"//Main Header Line 1 (Thank you Dixon)
#define REPLNEFORMT2 "       %40.2f%18.2f%8.2f\n\n"//Main Header Line 2 (Thank you Dixon)
#define MAX_SIZE 5
int struct_cmp_by_product(const void *a, const void *b);
void print_struct_array_pre(EmployeeRecord MyAssociate[]);
void print_struct_array_post(EmployeeRecord MyAssociate[]);

void print_struct_array_pre(EmployeeRecord MyAssociate[]) 
{ 
    int i;
         printf("       ***********ARRAY BEFORE NOT BEEN SORTED YET***************\n");
    for(i=0; i<MAX_SIZE; i++) 
    {
        //printf("%s %s]\n", MyAssociate[i].Lastname, MyAssociate[i].Firstname);
        fprintf(stdout,REPLNEFORMT1,MyAssociate[i].FullName,MyAssociate[i].Payrate,
            MyAssociate[i].Hours<=40?MyAssociate[i].Hours:40,MyAssociate[i].Gross,MyAssociate[i].FedTax,
            MyAssociate[i].SsiTax,MyAssociate[i].NetPay);  
        fprintf(stdout,REPLNEFORMT2,MyAssociate[i].OVT,MyAssociate[i].StateTax,MyAssociate[i].Defr);
    }
} 
int struct_cmp_by_product(const void *a, const void *b) 
{ 
    struct EmployeeRecord *ia = (struct EmployeeRecord *)a;
    struct EmployeeRecord *ib = (struct EmployeeRecord *)b;
    return strcmp(ia->FullName, ib->FullName);
    /* strcmp functions works exactly as expected from
    comparison function */
}
void print_struct_array_post(EmployeeRecord MyAssociate[]) 
{ 
    int i;
         printf("       ***********ARRAY HAS BEEN SORTED VIA QUICK-SORT***************\n");
    for(i=0; i<MAX_SIZE; i++) 
    {
        //printf("%s %s]\n", MyAssociate[i].Lastname, MyAssociate[i].Firstname);
        fprintf(stdout,REPLNEFORMT1,MyAssociate[i].FullName,MyAssociate[i].Payrate,
            MyAssociate[i].Hours<=40?MyAssociate[i].Hours:40,MyAssociate[i].Gross,MyAssociate[i].FedTax,
            MyAssociate[i].SsiTax,MyAssociate[i].NetPay);  
        fprintf(stdout,REPLNEFORMT2,MyAssociate[i].OVT,MyAssociate[i].StateTax,MyAssociate[i].Defr);
    }
} 

2 个答案:

答案 0 :(得分:0)

如果compare函数与调用qsort()的源文件位于不同的源文件中,则在调用qsort()的源文件中将compare函数声明为external。 qsort()在stdlib.h中声明为外部。所以没有问题。如果这是c ++,你也可以使用std :: sort()或std :: stable_sort(),但你已经将它标记为c?

所以在main.c中,添加以下行:

extern int struct_cmp_by_product(const void *a, const void *b);

答案 1 :(得分:0)

以下是您似乎正在做的事情的自包含示例。虽然它没有给我编译为vanilla c ++的visual studio上的任何编译器错误。

main.cpp中:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

extern int cmp_char(const void *a, const void *b);

int main(void)
{
    char arr[13] = "cbacbacbacba";

    qsort(arr, sizeof(arr) - 1, sizeof(char), cmp_char);

    printf("arr = %s\n", arr);
    getchar();
    return 0;
}

other.cpp:

#include <stdio.h>
#include <string.h> 

int cmp_char(const void *a, const void *b);

int cmp_char(const void *a, const void *b) 
{ 
   char *pa = (char*)a;
   char *pb = (char*)b;

   return *pa - *pb;
}

注意:您的示例已经在main.cpp中对另一个文件中的函数进行了extern引用,因此我不明白为什么您会收到错误。难道你在编译器命令行上需要两个c ++文件吗? (所以它知道编译并将两个文件链接在一起吗?)