2017-02-11 21 views
0

Я пытаюсь вызвать QSort с моим компаратором с использованием массива структур студента ' имеет атрибуты:компаратор не вызывая в QSort [Ошибка: Ожидается выражение перед тем компаратора]

typedef struct 
{ 
    int ID;      // 4 bytes    = 164 [+ int] 
    char firstname[NAME_LENGTH]; // 1 bytes * length (80) = 160 [2 * NAME_LENGTH] 
    char lastname[NAME_LENGTH]; // 1 bytes * length (80) 
} Student; 

Мой код пытается вызывать qsort из функции 3 раза: сортировать по идентификатору, затем имя, затем фамилию. Основная функция - вызов других функций для чтения и записи. Поиск ошибки в одном должен заставить меня применить ее к другой функции, правильно? Однако функции, связанные с сортировкой являются:

#ifdef TEST_SORTID 
void StudentSortbyID(Student * stu, int numelem) 
{ 
    qsort(&(stu-> ID), numelem, sizeof(stu), compareInts); 
} 
#endif 

#ifdef TEST_SORTFIRSTNAME 
void StudentSortbyFirstName(Student * stu, int numelem) 
{ 
    qsort(&(stu-> firstname), numelem, sizeof(stu), compareStrings); 
} 
#endif 

#ifdef TEST_SORTLASTNAME 
void StudentSortbyLastName(Student * stu, int numelem) 
{ 
    qsort(&(stu-> lastname), numelem, sizeof(stu), compareStrings); 
} 
#endif 

#ifdef TEST_COMPAREINTS 
int compareInts(const void * argu1, const void * argu2) 
{ 
    const int * iptr1 = (const int *) argu1; //convert void to integer pointer 
    const int * iptr2 = (const int *) argu2; 
    int ival1 = * iptr1;      //convert pointer to value 
    int ival2 = * iptr2; 
    if(ival1 < ival2)  { return -1; } //return -1 if first value is less 
    if(ival1 > ival2)  { return 1; } //return 1 if previous value is greater 
    if(ival1 == ival2)  { return 0; } //return 0 if the adjacent values are equal 
} 
#endif 

#ifdef TEST_COMPARESTRINGS 
int compareStrings(const void * argu1, const void * argu1) 
{ 
    //String is an array of characters (string = char*) -> pointing to string 
    const char * const * sptr1 = (const char * *) argu1; //converting empty pointers to strings which point to characters [**] 
    const char * const * sptr2 = (const char * *) argu2; 
    const char * string1 = * sptr1;      // a string is a character pointer 
    const char * string2 = * sptr2; 
    return strcmp(string1,string2); 
} 
#endif 

Ошибки я получаю при запуске GCC является:

student.c:120: error: too few arguments to function ‘compareInts’ 

Я думал, что компаратор QSort в не принимает аргументы? Когда я пытаюсь поместить в 1-й два элемента массива, это тоже ошибки. Есть идеи?

+0

И мы не должны разбирать, с какими линиями может возникнуть сообщение об ошибке? К сожалению, мы не являемся сервисом debugginmg. – Olaf

+1

Вы объявляете функции сравнения перед вызовами qsort? – dromtrund

+0

Извините, что ошибка возникла в строке 4 @Olaf –

ответ

0

Я предлагаю решить одну вещь за другой, то есть начать с сортировки по идентификатору, предоставить определенную функцию sortStudentById-compparator и начать с кода без каких-либо #ifdef (они обычно делают отладку и понимание ошибок компилятора более сложный).

Я полагаю, что одна из причин заключается в том, что ваша функция сравнения не объявлена ​​до ее использования в qsort.

Как только вы это решите, вы наверняка столкнетесь с следующей проблемой при использовании qsort. Если вы хотите сортировать объекты-ученики, ваша функция сравнения должна принимать указатели на объекты-ученики (тогда как qsort будет многократно обменивать студенческие объекты в целом, а не указатели на них). Передача указателя на член в qsort (например, &(stu-firstname)) позволит qsort заменять вещи таким образом, чтобы это точно не предназначалось.

Попробуйте следующий код в качестве отправной точки и сделать Адаптации в соответствии с требованиями:

int compareStudentsByID(const void* s1, const void *s2) { 
    return ((Student *)s1)->ID - ((Student*)s2)->ID; 
} 

void sortByID(Student *s) { 

    qsort(s,100,sizeof(Student),compareStudentsByID); 
} 

int main() { 

    Student students[100]; 
    for (int i=0; i<100; i++) { 
     students[i].ID = rand()%1000; 
    } 
    sortByID (students); 

    return 0; 
} 
+0

К сожалению, я не могу удалить инструкции ifdef, поскольку они используются для частичной классификации кредитов. Функция объявлена ​​в файле заголовка следующим образом: int compareInts (const void * argument1, const void * argument2); int compareStrings (const void * argument1, const void * argument2); Однако я делаю корректировки qsort, и я дам вам знать, как это работает! Спасибо! –

+0

Я переместил функции перед сортировкой функции и modififed qsort, и я получаю еще одну знакомую ошибку. Неопределенная ссылка –

+0

вы можете разместить свой код? –

0
// Do not remove #ifdef ... #endif before and after each function. 
// 
// They are used to test different functions in your program and give 
// partial credits, in case your program does not work completely. 

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

void StudentPrint(Student * stu, int num) 
{ 
    printf("There are %d students\n", num); 
    for (int ind = 0; ind < num; ind ++) 
    { 
     printf("ID = %d, First Name = %s, Last Name = %s\n", 
     stu[ind].ID, stu[ind].firstname, stu[ind].lastname); 
    } 
} 

#ifdef TEST_READ 
// return false if anything is wrong 
// return true if reading the file successfully and the data is save in 
// the allocated memory 
// input: filename, the name of the input file 
// output: address of the allocated memory 
// output: number of students 
bool StudentRead(char * filename, Student * * stu, int * numelem) 
{ 
    int id; 
    char first[NAME_LENGTH]; 
    char last[NAME_LENGTH]; 
    // open the file to read 
    FILE * inputPtr = fopen(filename, "r"); 

    // if fopen fails, return false 
    // do not use fclose since fopen already fails 
    if (inputPtr == NULL) 
    { 
     fprintf(stderr, "File Opening failed; Evaluate read function\n"); 
     return false; 
    }  

    // count the number of lines to determine the number of students 
    while(0 != fscanf(inputPtr, "\n")) { numelem++; } 


    // return to the beginning of the file 
    // you can use fseek or 
    // fclose followed by fopen 
    // You need to check whether fseek or fopen fails 
    // Do not use rewind because it does not report whether it fails 
    fclose(inputPtr); 
    inputPtr = fopen(filename, "r");   // reading starts from 0 

    // allocate memory for the data 
    stu = malloc(((sizeof(*(stu))) * (*numelem))); 

    // check whether memory allocation fails 
    if (stu == NULL) 
    { 
     fprintf(stderr, "Memory allocation failed; evaluate malloc\n"); 
     return false; 
    } 

    // read the data from the file and store the data in the allocated memory 
    for (int count = 0; count < *numelem; count++) 
    { 
     fscanf(inputPtr, "%i %s %s\n", &id, &first[NAME_LENGTH], &last[NAME_LENGTH]); 

     stu[count] -> ID = id; 
     stu[count] -> firstname[NAME_LENGTH] = first[NAME_LENGTH]; 
     stu[count] -> lastname[NAME_LENGTH] = last[NAME_LENGTH]; 
    } 
     if (stu[0] == NULL) 
    { 
     fprintf(stderr, "Inputting file values to variable failed; evluate read function\n"); 
     return false; 
    } 
    // close the file 
fclose(inputPtr); 

    return true; 
} 
#endif 

#ifdef TEST_WRITE 
// return false if anything is wrong 
// return true if writing the file successfully 
// input: filename, the name of the output file 
// input: address of the student array 
// input: number of students 

bool StudentWrite(char * filename, Student * stu, int numelem) 
{ 

    // open the file to write 
    FILE * outputFile = fopen(filename, "w"); 

    // if fopen fails, return false 
    // do not use fclose since fopen already fails 
    if (outputFile == NULL) 
    { 
     fprintf(stderr, "Opening file failed; evaluate Write function\n"); 
     return false; 
    } 
    // write the students to the output file 
    for (int count = 0; count < numelem; count++) 
    { 
     fprintf(outputFile, "%i %s %s\n", (stu[count]).ID, (stu[count]).firstname, (stu[count]).lastname); 
    } 
    return true; 
} 
#endif 

#ifdef TEST_SORTID 
void StudentSortbyID(Student * stu, int numelem) 
{ 
    qsort(stu, numelem, sizeof(Student), compareInts); 
} 
#endif 

#ifdef TEST_SORTFIRSTNAME 
void StudentSortbyFirstName(Student * stu, int numelem) 
{ 
    qsort(stu -> firstname, numelem, sizeof(stu), compareStrings); 
} 
#endif 

#ifdef TEST_SORTLASTNAME 
void StudentSortbyLastName(Student * stu, int numelem) 
{ 
    qsort(stu -> lastname, numelem, sizeof(stu), compareStrings); 
} 
#endif 

int compareInts(const void * argu1, const void * argu2) 
{ 
    const Student * iptr1 = (const Student *) argu1; //convert void to integer pointer 
    const Student * iptr2 = (const Student *) argu2; 
    return iptr1 ->ID - iptr2 -> ID; 
} 

int compareStrings(const void * argu1, const void * argu2) 
{ 
    //String is an array of characters (string = char*) -> pointing to string 
    const Student * sptr1 = (const char *) argu1; //converting empty pointers to strings which point to characters [**] 
    const Student * sptr2 = (const char *) argu2; 
    const char string1 = sptr1 -> firstname;       // a string is a character pointer 
    const char string2 = sptr2 -> firstname; 
    return strcmp(string1,string2); 

} 

Это весь код для этих функций. Другой .c содержит основные

+0

С этим я сталкиваюсь с ошибками с функцией сравнения строк. initializaiton из несовместимого типа указателя среди других. Я пытаюсь исправить их сейчас –

+0

Код компилируется сейчас. Не удалось создать мой makefile, но это другая тема –

 Смежные вопросы

  • Нет связанных вопросов^_^