把原文件的学生进行排名后写回原文件

有一个记录学生信息的文件,每一行记录一名学生的信息,格式如下:
学号\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;
}

猜你喜欢

转载自blog.csdn.net/qq_43496435/article/details/113777568