简体   繁体   English

使用qsort按字母顺序组织结构

[英]Organizing a struct in alphabetical order with qsort

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

#define ARRAY_MAX 100
#define FNAME 31
#define LNAME 31

typedef int (*compfn)(const void*, const void*);

struct student {

    char firstName[FNAME];
    char lastName[LNAME];
    int quiz1, quiz2 , quiz3, quiz4, mid1, mid2, final;
    char letterGrade;
    int finalGradePercentage;
};

// Function for Qsort
int compare(struct student *element1, struct student *element2)
{
    if ( element1->firstName[0] < element2->firstName[0])
        return -1;

    else if (element1->firstName[0] > element2->firstName[0])
        return 1;

    else
        return 0;
    }


int main(int argc, char *argv[]){


    FILE *inputFile, *outputFile;
    char buf[100];
    char *token;
    int count = 0;

    inputFile = fopen("/Users/Home/Desktop/input_data.txt", "r");


    struct student studentData[ARRAY_MAX];
    while (fgets(buf, sizeof(buf), inputFile) != NULL){ //scan through the input file
        token = strtok(buf, " ");
        strcpy(studentData[count].firstName, token);
        token = strtok(NULL, ",");
        strcpy(studentData[count].lastName, token);
        token = strtok(NULL, ",");
        studentData[count].quiz1 = atoi(token);
        token = strtok(NULL, ",");
        studentData[count].quiz2 = atoi(token);
        token = strtok(NULL, ",");
        studentData[count].quiz3 = atoi(token);
        token = strtok(NULL, ",");
        studentData[count].quiz4 = atoi(token);
        token = strtok(NULL, ",");
        studentData[count].mid1 = atoi(token);
        token = strtok(NULL, ",");
        studentData[count].mid2 = atoi(token);
        token = strtok(NULL, ",");
        studentData[count].final= atoi(token);


        studentData[count].finalGradePercentage = studentData[count].quiz1 * .10 +studentData[count].quiz2 * .10 + studentData[count].quiz3 * .10 + studentData[count].quiz4 * .10 + studentData[count].mid1 * .20 + studentData[count].mid2 * .15 + studentData[count].final * .25;

        if (studentData[count].finalGradePercentage <=100 &&  studentData[count].finalGradePercentage>=90 )
        {
            studentData[count].letterGrade = 'A';
        }
        else if(studentData[count].finalGradePercentage <= 89 && studentData[count].finalGradePercentage >=80)
        {
            studentData[count].letterGrade = 'B';
        }
        else if(studentData[count].finalGradePercentage <= 79 && studentData[count].finalGradePercentage >=70)
        {
            studentData[count].letterGrade = 'C';
        }
        else if(studentData[count].finalGradePercentage <= 69 && studentData[count].finalGradePercentage >=60)
        {
            studentData[count].letterGrade = 'D';
        }
        else if(studentData[count].finalGradePercentage <= 59){
            studentData[count].letterGrade = 'F';
        }


        count++;
    }


    qsort((void *) &studentData,count,sizeof(struct student),(compfn)compare);           


    for (int i = 0; i< count; i++) {
        char name[62];

        sprintf(name, "%s %s", studentData[i].firstName, studentData[i].lastName);
        printf("%-20s %c\n", name, studentData[i].letterGrade);

    }

    fclose(inputFile);
    fclose(outputFile);

    return 0;
}

Hi Guys I'm having a tough time getting my struct organized in alphabetical order. 嗨,大家好,我很难按字母顺序组织我的结构。 Any help doing so would be greatly appreciated. 任何帮助这样做将不胜感激。 This is what I have so far. 到目前为止,这就是我所拥有的。 I think the problem is the in the compare function. 我认为问题出在比较功能中。 But I'm not sure I really understand qsort all that well. 但是我不确定我是否真的很了解qsort。 Anyone one know of some good references for reading up on it. 任何人都知道一些很好的参考资料可以阅读。

Using your existing structure, you are comparing the first character of the first name, only. 使用现有结构,您仅在比较名字的第一个字符。 You need to compare strings with strcmp() , and given that there could be two students called John or Jane in a class, you probably want to compare on last name too. 您需要将字符串与strcmp()进行比较,并且鉴于一堂课中可能有两个叫John或Jane的学生,您可能也想比较姓氏。

int compare(struct student *element1, struct student *element2)
{
    if ((rc = strcmp(element1->firstName, element2->firstName)) != 0)
        return rc;
    return strcmp(element1->lastName, element2->lastName);
}

On the whole, I prefer to write comparison functions as: 总体而言,我更喜欢将比较函数编写为:

int compare(const void *v1, const void *v2)
{
    const struct student *p1 = (struct student *)v1;
    const struct student *p2 = (struct student *)v2;

    if ((rc = strcmp(p1->firstName, p2->firstName)) != 0)
        return rc;
    return strcmp(p1->lastName, p2->lastName);
}

I then don't have to cast the pointer to qsort() since the pointer to function is of the same type that qsort() expects. 然后,我不必将指针qsort()qsort()因为指向函数的指针与qsort()期望的类型相同。 In practice, there isn't much difference. 在实践中,并没有太大的区别。

See also How to sort an array of structs in C? 另请参见如何在C中对结构数组进行排序?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM