有一个记录学生信息的文件,每一行记录一名学生的信息,格式如下:
学号\t 姓名\t 性别\t 分数 1\t 分数 2\t 分数 3\n.
A. 要求读取文件的内容, 串成一个链表。
B. 按照总分递减排序将结果保存到原文件
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct stu
{
int num;
char name[100];
char gender;
int score1;
int score2;
int score3;
int sum;
struct stu *next;
}Stu_t , *pStu_t;
//插入链表结点:尾插
void tailInsert(pStu_t *Head , pStu_t *Tail , pStu_t p)
{
if (*Head == NULL)//空链表
{
*Head = p;
*Tail = p;
}
else
{
(*Tail)->next = p;
*Tail = p;
}
}
//数组元素是pStu_t, 递减排序
int cmp(const void *a , const void *b)
{
pStu_t *p1 = (pStu_t *) a;
pStu_t *p2 = (pStu_t *) b;
if ((*p1)->sum > (*p2)->sum)
{
return -1;
}
else if((*p1)->sum < (*p2)->sum)
{
return 1;
}
else
{
return 0;
}
}
int main(int argc , char *argv[])
{
FILE *fp = fopen(argv[4] , "rb");
if (fp == NULL)
{
perror("fopen:");
return -1;
}
pStu_t Head = NULL;
pStu_t Tail = NULL;
int count = 0;//学生信息的行数
while (!feof(fp))
{
pStu_t p = (pStu_t) calloc(1 , sizeof(Stu_t));
//没有if判断,count会把算上最后的回车行
if (fscanf(fp , "%d\t%s\t%c\t%d\t%d\t%d" , &p->num , p->name , &p->gender , &p->score1 , &p->score2 , &p->score3) != EOF)
{
p->sum = p->score1 + p->score2 + p->score3;
tailInsert(&Head , &Tail , p);
count++;
}
}
fclose(fp);
//A是按总分递减存所有Stu_t结点指针的数组
pStu_t *A = (pStu_t *) calloc(1,count*sizeof(pStu_t));
pStu_t p = Head;
int i = 0;
while (p != NULL)
{
A[i++] = p;
p = p->next;
}
qsort(A , count , sizeof(pStu_t) , cmp); //按照总分递减排序
fp = fopen(argv[4] , "wb");
if (fp == NULL)
{
perror("fopen:");
return -1;
}
//把按照总分递减排序的结果写回原文件
for (int i = 0; i < count; i++)
{
fprintf(fp , "%d\t%s\t%c\t%d\t%d\t%d\n" , A[i]->num , A[i]->name , A[i]->gender , A[i]->score1 , A[i]->score2 , A[i]->score3);
}
fclose(fp);
return 0;
}