使用文件流插入代码

时间:2017-06-04 12:39:22

标签: c sorting insertion-sort

以下是我正在处理的任务:

我收到一个txt文件,其中包含学生姓名,身份证号码,学校,专业和考试成绩列表。

  • 阅读此内容并复制到C中的结构。

  • 使用插入排序对此列表进行排序。

  • 在屏幕上打印已排序的列表。

我通过静音某些部分检查了我的编码,我的插入排序功能出错了。

我不知道哪个部分不正确。这一切都对我有意义。我需要帮助:(这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1000
#define BUF_SIZE 80
typedef struct {
        char name[20];
        char studentID[10];
        char department[20];
        char major[20];
        int mid;
        int final;
} student;
FILE *fp;
void operation(student t, student list[], int j);
void insertion_sort(student list[], int n);
void printing(student list[], int n);

int main(int argc, char *argv[])
{
        char filename[20] = "studentlist.txt";

        int n = 1;              /* (number of students) + 1 */
        student list[MAX];
        char buffer[BUF_SIZE];
        int i;
        fp = fopen(filename, "r");
        while (1) {
                if (fgets(buffer, BUF_SIZE, fp) == NULL)
                        break;
                strncpy(list[n].name, buffer, strlen(buffer) - 1);
                fgets(buffer, BUF_SIZE, fp);
                strncpy(list[n].studentID, buffer, strlen(buffer) - 1);
                fgets(buffer, BUF_SIZE, fp);
                strncpy(list[n].department, buffer, strlen(buffer) - 1);
                fgets(buffer, BUF_SIZE, fp);
                strncpy(list[n].major, buffer, strlen(buffer) - 1);
                fgets(buffer, BUF_SIZE, fp);
                list[n].mid = atoi(buffer);
                fgets(buffer, BUF_SIZE, fp);
                list[n].final = atoi(buffer);
                n++;
        }

        fclose(fp);
        insertion_sort(list, n);
        printing(list, n);
        return 0;
}

void insertion_sort(student list[], int n)
{
        int i;
        student temp;
        for (i = 2; i < n; i++) {
                temp = list[i];
                operation(temp, list, i - 1);
        }

}

void operation(student t, student list[], int j)
{
        list[0] = t;
        while (t.studentID < list[j].studentID) {
                list[j + 1] = list[j];
                j--;
        }
        list[j + 1] = t;
}

void printing(student list[], int n)
{
        int i;
        for (i = 1; i < n; i++) {
                printf(" %s  ", list[i].name);
                printf(" %s  ", list[i].studentID);
                printf(" %s  ", list[i].department);
                printf(" %s  ", list[i].major);
                printf(" %6d  ", list[i].mid);
                printf(" %6d  ", list[i].final);
                putchar('\n');
        }
}

1 个答案:

答案 0 :(得分:0)

继续评论和第一个答案,您正在分割insertion_sortoperation功能之间的跟踪索引错误。当一个人工作时(并且可以说更小),不需要两个功能。从分裂中获得的好处很少(除了增加的混淆)。

将一个简单的插入排序放在一个适合您需要的函数中(并使用指针进行排序而不是重复使用函数copy-constructor来完成交换),您可以执行类似以下操作:

typedef struct {
    int id, g;
} student;

void insertion_sort (student **list, int nmemb)
{
    for (int i = 0; i < nmemb; i++)
        for (int j = i; j > 0 && list[j]->id < list[j-1]->id; j--)
        {
            student *tmp  = list[j];
            list[j]   = list[j-1];
            list[j-1] = tmp;
        }
}

汇总一个简短的(有限的结构成员示例),您可以执行以下操作,按ID(或下面的id)对学生数据进行排序

#include <stdio.h>

typedef struct {
    int id, g;
} student;

void insertion_sort (student **list, int nmemb)
{
    for (int i = 0; i < nmemb; i++)
        for (int j = i; j > 0 && list[j]->id < list[j-1]->id; j--)
        {
            student *tmp  = list[j];
            list[j]   = list[j-1];
            list[j-1] = tmp;
        }
}

void printing(student *list[], int n)
{
    int i;
    for (i = 0; i < n; i++) {
        printf(" %d  ", list[i]->id);
        printf(" %d  \n", list[i]->g);
    }
}

int main (void) {

    student s[] = { {.id = 5, .g = 72},    /* minimal student test data */
                    {.id = 2, .g = 91},
                    {.id = 4, .g = 77},
                    {.id = 1, .g = 96},
                    {.id = 3, .g = 85}};
    int n = sizeof s / sizeof *s;
    student *l[n];

    for (int i = 0; i < n; i++)  /* initialize pointers in l */
        l[i] = &s[i];

    insertion_sort (l, n);       /* sort pointers in l */
    printing (l, n);             /* output sorted pointers */

    return 0;
}

示例使用/输出

按student.id排序

$ ./bin/inssort_so
 1   96
 2   91
 3   85
 4   77
 5   72

如果你确实想避免使用传递指针数组所涉及的额外级别的间接(实际上是指向指针到类型的指针),你可以使你的原始方法工作如下:

void insertion_sort (student *list, int nmemb)
{
    for (int i = 0; i < nmemb; i++)
        for (int j = i; j > 0 && list[j].id < list[j-1].id; j--)
        {
            student tmp  = list[j];
            list[j]   = list[j-1];
            list[j-1] = tmp;
        }
}

void printing (student *list, int n)
{
    for (int i = 0; i < n; i++)
        printf (" %d   %d  \n", list[i].id, list[i].g);
}

int main (void) {

    student s[] = { {.id = 5, .g = 72},
                    {.id = 2, .g = 91},
                    {.id = 4, .g = 77},
                    {.id = 1, .g = 96},
                    {.id = 3, .g = 85}};
    int n = sizeof s / sizeof *s;

    insertion_sort (s, n);
    printing (s, n);

    return 0;
}

在前进时,还要考虑将 compare 回调函数传递给排序例程。这允许您使用相同的排序例程对许多不同类型的数据进行排序 - 只需更改 compare 函数(就像对C库qsort例程所做的那样。