2011-05-03 88 views
3

我在使用我們應該寫的函數時遇到了一些麻煩。據說,這是它應該如何工作,但它給了我不兼容的指針類型錯誤,我不知道如何解決它。從不兼容的指針類型中傳遞'qsort'的參數4

問題出在引用compare_last函數的qsort中。

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

#define MAX_PERSONS 100 

//person structure definition goes here 
typedef struct{ 
    char last[32]; 
    char first[32]; 
    int year; 
}Person; 

//function declarations go here 
int compare_last(Person * ptr1, Person * ptr2); 

void main(void){//main function goes here 
    char *infilename[20]; 
    char *outfilename[20]; 
    FILE * fptrin; 
    FILE * fptrout; 
    int i, j; 
    Person musicians[MAX_PERSONS]; 
    printf("Enter input file name: "); 
    scanf("%s", infilename); 
    printf("Enter output file name: "); 
    scanf("%s", outfilename); 
    strcat(*outfilename, ".htm"); 
    fptrin = fopen(*infilename, "r"); 
    fptrout = fopen(*outfilename, "w"); 

    for(i = 0; i < MAX_PERSONS; i++) 
    { 
     fscanf(fptrin, "%s %s %i", musicians[i].last, musicians[i].first, &musicians[i].year); 
    } 

    qsort(musicians, i, sizeof(musicians[0]), compare_last); 

    fprintf(fptrout, "<html>\n<body>\n<title>LAB14</title>\n"); 

    for(j = 0; j < i; j++) 
    { 
     fprintf(fptrout, "%s %s %i <br>", musicians[j].last, musicians[j].first, musicians[j].year); 
    } 

    fprintf(fptrout, "</body>\n</html>\n"); 
    fclose(fptrin); 
    fclose(fptrout); 

}//end main 

//function definitions go here 

int compare_last(Person * ptr1, Person * ptr2) 
{ 
    int result = strcmp(ptr1 -> last, ptr2 -> last); 
    if(result != 0) 
     return result; 
    else 
     return strcmp(ptr1 -> first, ptr2 -> first); 
} 
+0

你寫'我們應該寫作' - 這是否意味着這是作業? – 2011-05-03 05:55:50

回答

4
int compare_last(Person * ptr1, Person * ptr2); 

應該

int compare_last(void * ptr1, void * ptr2); 

然後,你需要內compare_last

+1

好的,我該如何投射指針?我正在嘗試的所有內容都無法正常工作,並且找不到任何解決方案。 – Sam 2011-05-03 06:12:59

+0

'Person * personPtr1 =(Person *)ptr1;' – Erik 2011-05-03 06:15:27

+0

它仍然給我不兼容的指針類型錯誤....我使用qsort錯了嗎?我將代碼更改爲int compare_last(void * ptr1,void * ptr2) {* PersonPtr1 =(Person *)ptr1; Person * personPtr2 =(Person *)ptr2; int result = strcmp(personPtr1 - > last,personPtr2 - > last); if(result!= 0) 返回結果; else return strcmp(personPtr1 - > first,personPtr2 - > first); } – Sam 2011-05-03 06:19:20

2

原型投給qsort()是:

void qsort(void *base, size_t nmemb, size_t size, 
      int(*compar)(const void *, const void *)); 

因此,Y我們的排序功能需要匹配int(*compar)(const void *, const void *),或者您需要在調用qsort()時進行投射。

如果要排序Person*,最簡單的方法是聲明所需的排序功能,再抹上內部功能:

static int compare_last(const void *ptr1, const void *ptr2) 
{ 
    const Person *p1 = ptr1, *p2 = ptr2; 
    int result = strcmp(p1 -> last, p2 -> last); 
    ... 
} 

沒有必要在所有投的話,因爲const void *轉換就好了到const Person *

+1

在這裏鑄造一個不匹配的函數指針會調用未定義的行爲,因爲'qsort'會用錯誤的參數類型('const void *'而不是'Person *')調用它。 – 2011-05-03 12:47:37

+0

@R:好的,很高興知道。我期望大多數編譯器在那裏產生一些明智的東西,因爲const void *和Person *都很可能以相同的方式表示,但是未定義當然值得避免。 – unwind 2011-05-03 14:27:56

+0

是的,在實踐中(和在POSIX上)所有指針都具有相同的表示形式,但最好避免依賴於此,如果您不需要,並且有另一種方法可以編寫清晰且100%符合的代碼。 – 2011-05-03 14:36:11

相關問題