我正在编写一个程序,按名称和等级对学生列表进行排序。我在尝试编译时收到以下错误:
ex11.c: In function 'compareByGrade': ex11.c:46: error: request for member 'grade' in something not a structure or union ex11.c:47: error: request for member 'grade' in something not a structure or union ex11.c: In function 'compareByName': ex11.c:56: error: request for member 'name' in something not a structure or union ex11.c:57: error: request for member 'name' in something not a structure or union
这是头文件:
#define CLASS_SIZE 10
struct student {
char *name;
int idnumber;
char grade;
};
这是主文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ex11.h"
int main(void)
{
int c, i;
FILE *data;
struct student tmp, class[CLASS_SIZE];
void *nameArray[CLASS_SIZE], *gradeArray[CLASS_SIZE];
static int compareByGrade(const void *first, const void *second);
static int compareByName(const void *first, const void *second);
data = fopen("data", "r"); /* open data file */
/* Move data into struct */
for (i = 0; i < CLASS_SIZE; ++i) {
fscanf(data, "%s%d%c", tmp.name, tmp.idnumber, tmp.grade);
class[i].name = tmp.name;
class[i].idnumber = tmp.idnumber;
class[i].grade = tmp.grade;
}
fclose(data); /* close data file */
qsort(nameArray, CLASS_SIZE, sizeof(*nameArray), &compareByName);
qsort(gradeArray, CLASS_SIZE, sizeof(*gradeArray), &compareByGrade);
}
/* Function to sorty by grade */
static int compareByGrade(const void *first, const void *second)
{
const char *firstGrade = (*(const char **) first) -> grade; /* line 46 */
const char *secondGrade = (*(const char **) second) -> grade; /* line 47 */
return strcmp(firstGrade, secondGrade);
}
/* Function to sort by name */
static int compareByName(const void *first, const void *second)
{
const char *firstName = (*(const char **) first) -> name; /* line 56 */
const char *secondName = (*(const char **) second) -> name; /* line 57 */
return strcmp(firstName, secondName);
}
我做错了什么?
答案 0 :(得分:1)
同意xaxxon。 程序处理struct student类,nameArray和gradeArray永远不会被初始化。
BTW,我想不要使用一个名为class的结构,它与C ++的关键字混淆。
grade是char,但是strcmp()需要字符串来比较。
建议: 在main()中,
qsort(class, CLASS_SIZE, sizeof(struct student*), &compareByName);
qsort(class, CLASS_SIZE, sizeof(struct student*), &compareByGrade);
和外面,
int compareByGrade(const void *first, const void *second)
{
const char firstGrade = ((struct student *)first) -> grade;
const char secondGrade = ((struct student *)second) -> grade;
return firstGrade<secondGrade?-1:(firstGrade==secondGrade?0:1);
}
/* Function to sort by name */
int compareByName(const void *first, const void *second)
{
const char *firstName = ((struct student *)first) -> name;
const char *secondName = ((struct student *)second) -> name;
return strcmp(firstName, secondName);
}
compareByGrade()的返回值的表达式将以compareByName()
的相同方式起作用答案 1 :(得分:0)
const char *firstGrade = (*(const char **) first) -> grade;
const char *secondGrade = (*(const char **) second) -> grade;
'first'被强制转换为指向char的双指针,然后取消引用,所以你有一个char *。然后你用 - &gt;取消引用它到char,char不是结构或联合,也没有成员等级(因为它不能)。
名称相同的问题。
那就是说,我看不到你在哪里填充nameArray或gradeArray,所以即使你修复了编译错误,你也会遇到很多运行时错误。
答案 2 :(得分:0)
有很多事情你做错了。其中包括:
const struct student *
伪装成const void *
。fopen()
或fscanf()
是否正常工作。这是基于你写的内容(松散地)的工作代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CLASS_SIZE 10
struct student
{
char name[20];
int idnumber;
char grade;
};
static int compareByGrade(const void *first, const void *second);
static int compareByName(const void *first, const void *second);
static void print_students(const char *tag, const struct student *class, size_t size);
int main(void)
{
FILE *data;
if ((data = fopen("data", "r")) == 0)
{
fprintf(stderr, "failed to open file data\n");
exit(1);
}
struct student class[CLASS_SIZE];
for (int i = 0; i < CLASS_SIZE; ++i)
{
char name[20];
int idnumber;
char grade;
if (fscanf(data, "%19s %d %c", name, &idnumber, &grade) != 3)
{
fprintf(stderr, "failed to read student %d\n", i);
exit(1);
}
strcpy(class[i].name, name);
class[i].idnumber = idnumber;
class[i].grade = grade;
}
fclose(data);
qsort(class, CLASS_SIZE, sizeof(class[0]), &compareByName);
print_students("By name", class, CLASS_SIZE);
qsort(class, CLASS_SIZE, sizeof(class[0]), &compareByGrade);
print_students("By grade", class, CLASS_SIZE);
return 0;
}
static int compareByGrade(const void *p1, const void *p2)
{
const struct student *s1 = (const struct student *)p1;
const struct student *s2 = (const struct student *)p2;
if (s1->grade > s2->grade)
return +1;
else if (s1->grade < s2->grade)
return -1;
else
return strcmp(s1->name, s2->name);
}
static int compareByName(const void *p1, const void *p2)
{
const struct student *s1 = (const struct student *)p1;
const struct student *s2 = (const struct student *)p2;
return strcmp(s1->name, s2->name);
}
static void print_students(const char *tag, const struct student *class, size_t size)
{
printf("%s (%zu students):\n", tag, size);
for (size_t i = 0; i < size; i++)
printf("%2zu: %-20s %4d %c\n", i, class[i].name, class[i].idnumber, class[i].grade);
}
注意compareByName()
函数如何首先确定成绩等级,然后按名称进行比较。
student1 1234 A
student2 2345 B
junior03 3456 C
junior04 4356 D
sophomore12 5234 F
sophomore13 6345 B
senior19 3419 C
senior99 4399 D
fresher29 7456 C
fresher31 8356 A
By name (10 students):
0: fresher29 7456 C
1: fresher31 8356 A
2: junior03 3456 C
3: junior04 4356 D
4: senior19 3419 C
5: senior99 4399 D
6: sophomore12 5234 F
7: sophomore13 6345 B
8: student1 1234 A
9: student2 2345 B
By grade (10 students):
0: fresher31 8356 A
1: student1 1234 A
2: sophomore13 6345 B
3: student2 2345 B
4: fresher29 7456 C
5: junior03 3456 C
6: senior19 3419 C
7: junior04 4356 D
8: senior99 4399 D
9: sophomore12 5234 F