2011-05-03 3 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

우리는 '우리가 글을 쓸 것'이라고 씁니다 - 이것이 숙제라는 뜻입니까? –

답변

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

당신이 qsort()에 대한 compare_last

+1

좋아요, 어떻게 포인터를 캐스팅합니까? 노력하고있는 모든 것이 제대로 작동하지 않으며 솔루션을 찾을 수 없습니다. – Sam

+0

'Person * personPtr1 = (Person *) ptr1;' – Erik

+0

여전히 호환되지 않는 포인터 유형 오류가 발생합니다. qsort를 잘못 사용하고 있습니까? compare_last (void * ptr1, void * ptr2) 코드로 변경했습니다. { Person * personPtr1 = (Person *) ptr1; 사람 * personPtr2 = (사람 *) ptr2; int result = strcmp (personPtr1 -> last, personPtr2 -> last); if (result! = 0) 반환 결과; else return strcmp (personPtr1 -> first, personPtr2 -> first); } – Sam

2

프로토 타입 내에서 캐스팅 할 필요가 그런

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

해야하는 것입니다 :

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

따라서, y를 우리의 정렬 함수는 int(*compar)(const void *, const void *)과 일치해야하거나 qsort()를 호출 할 때 캐스트해야합니다.

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 *이 잘 변환하기 때문에 다음 캐스팅 전혀 필요가 없다 : 당신이 Person*을 정렬 할 경우

이, 가장 쉬운 방법이 필요로 분류 기능을 선언하는 것입니다, 다음 함수 내에서 캐스팅 const Person *.

+1

일치하지 않는 함수 포인터를 여기에 던지면'qsort'가 잘못된 인자 타입 ('Person *'대신'const void *')으로 호출하기 때문에 정의되지 않은 동작을 호출합니다. –

+0

@R : 알겠습니다. 잘 알고 있습니다. 왜냐하면 const void *와 Person *은 같은 방식으로 표현 될 가능성이 높기 때문에 대부분의 컴파일러가 거기에서 의미있는 것을 생성 할 것으로 기대합니다. 그러나 undefinedness는 물론 피할 가치가 있습니다. – unwind

+0

예, 실제로 (그리고 POSIX에서) 모든 포인터는 똑같은 표현을 가지고 있지만, 실제로 필요하지 않은 경우에 의존하지 않는 것이 가장 좋습니다. 명확하고 100 % 준수하는 코드를 작성하는 다른 방법이 있습니다. –

관련 문제