#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;
}
嗨,大家好 我很难按字母顺序组织我的结构。任何帮助这样做将不胜感激。这就是我到目前为止所拥有的。我认为问题在于比较功能。但是我不确定我是否真的很了解qsort。任何人都知道一些很好的参考资料来阅读它。
答案 0 :(得分:1)
使用现有结构,您只是比较第一个名字的第一个字符。您需要将字符串与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);
}
总的来说,我更喜欢将比较函数写为:
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);
}
然后我不必将指针强制转换为qsort()
,因为指向函数的指针与qsort()
期望的类型相同。在实践中,没有太大区别。