0

我正在编写一个按姓名和年级对学生列表进行排序的程序。我在尝试编译时收到以下错误:

ex11.c:在函数“compareByGrade”中:
ex11.c:46:错误:在非结构或联合的情况下请求成员“等级”
ex11.c:47:错误:在非结构或联合的情况下请求成员“等级”
ex11.c:在函数“compareByName”中:
ex11.c:56:错误:在不是结构或联合的东西中请求成员“名称”
ex11.c:57:错误:在非结构或联合的情况下请求成员“名称”

这是头文件:

#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);
}

我究竟做错了什么?

4

3 回答 3

1

同意xaxxon。程序处理 struct student 类,nameArray 和gradeArray 从未初始化。

顺便说一句,我想不要使用名为 class 的结构,它与 C++ 的关键字混淆。

等级是字符,但 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() 的作用相同

于 2013-05-13T01:33:10.063 回答
0
const char *firstGrade = (*(const char **) first) -> grade;
const char *secondGrade = (*(const char **) second) -> grade;

'first' 被强制转换为指向 char 的双指针,然后取消引用,所以你有一个 char *。然后,您使用 -> 将其取消引用为 char,并且 char 不是结构或联合,并且没有成员等级(因为它不能)。

同样的问题较低的名称。

也就是说,我看不到你在哪里填充 nameArray 或gradeArray,所以即使你修复了编译错误,你也会有很多运行时错误。

于 2013-05-13T00:46:36.163 回答
0

你做错了很多事情。这些包括:

  • 通常,您会打印出对数组进行排序的结果(或者对它们做一些事情,如果只是为了让您验证数组是否已排序)。
  • 您通常会根据结构编写比较函数——例程将被const struct student *伪装成const void *.
  • 您有一个包含指针的数据结构,但您没有为该指针分配空间来指向。
  • 您读入了未分配的空间。
  • 您没有对此进行测试fopen()fscanf()正常工作。
  • 您的扫描格式字符串不允许 ID 号和成绩之间有空格。

这是基于(松散地)您编写的工作代码。

代码

#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
于 2013-05-13T05:02:02.693 回答