链表练习

//输入一个文件名或两个文件名(成绩表),解析内部学生成绩,然后计算总分,
//如果两个文件名,需要汇总两个表,然后按照成绩高低排列输出整表。
//(PS : 成绩表为CSV格式,已逗号分隔,暂不考虑异常输入。)

#include "count_grade.h"
#include <stdio.h>
#include<string.h>
#include <windows.h>

int main(int argc, char* argv[])
{
	FILE* fp = NULL;
	char* filename = NULL;
	char* file1_buf = NULL;
	char* line_buf = NULL;
	struct student stu[LSIZE] = { 0 };
	char ch = 0;
	int rows = 0;
	int first_line_len = 0;
	int line = 1;
	Item temp = { 0 };
	List student = NULL;

	FILE* fp2 = NULL;
	char* file2name = NULL;
	char* file2_buf = NULL;
	char* line2_buf = NULL;
	struct student stu2[LSIZE] = { 0 };
	char ch2 = 0;
	int rows2 = 0;
	int first_line_len2 = 0;
	int line2 = 1;
	Item temp2 = { 0 };
	List student2 = NULL;

	if (argc != 3)
	{
		printf("Usage:%s filemane\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	fp = fopen(argv[1], "rb");
	if (NULL == fp)
	{
		fprintf(stderr, "Can't open %s\n", argv[1]);
		exit(EXIT_FAILURE);
	}
	fseek(fp, 0L, SEEK_END);
	int size = ftell(fp);

	file1_buf = (char*)malloc(size + 1);
	memset(file1_buf, 0, size + 1);
	line_buf = (char*)malloc(size + 1);
	memset(line_buf, 0, size + 1);

	filename = argv[1];
	fp = fopen(filename, "rb");
	if (NULL == fp)
	{
		fprintf(stderr, "Can't open %s\n", filename);
		exit(EXIT_FAILURE);
	}


	//计算行数
	while (EOF != (ch = getc(fp)))
	{
		if ('\n' == ch)
		{
			++rows;
		}
	}
	rewind(fp);
	//计算第一行的字符数
	while ('\n' != (ch = getc(fp)))
	{
		++first_line_len;
	}
	//让句柄偏移到第二行
	fseek(fp, first_line_len + 1, SEEK_SET);

#if 0
	int index = 0;
	while (line < rows)
	{
		read_line(fp, line_buf, size); //读出每一行
		parse_line(line_buf, &(stu[index]), line);//把每一行写入结构体
		++line;
		++index;

	}
	for (index = 0; index < rows - 1; ++index)
	{
		calculate_total_grade(&(stu[index]), rows);
	}
#endif
	int index = 0;
	int valid_line_num = 0;
	while (line < rows)
	{
		read_line(fp, line_buf, size); //读出每一行
		valid_line_num += parse_line(line_buf, &(stu[index]));//把每一行写入结构体
		++line;
		++index;
	}

	InitializeList(&student);//初始化链表;
	for (int z = 0; z < valid_line_num; z++)
	{
		AddItem(&student, &stu[z]);
	}
	printf("show the information of file1: \n");
	//Showstudent(temp, &student);
	calculate_total_grade(&student);

	//打开第二个文件
	fp2 = fopen(argv[2], "rb");
	if (NULL == fp2)
	{
		fprintf(stderr, "Can't open %s\n", argv[2]);
		exit(EXIT_FAILURE);
	}
	fseek(fp2, 0L, SEEK_END);
	int size2 = ftell(fp2);
	file2_buf = (char*)malloc(size2 + 1);
	memset(file2_buf, 0, size2 + 1);
	line2_buf = (char*)malloc(size2 + 1);
	memset(line2_buf, 0, size2 + 1);
	file2name = argv[2];
	fp2 = fopen(file2name, "rb");
	if (NULL == fp2)
	{
		fprintf(stderr, "Can't open %s\n", file2name);
		exit(EXIT_FAILURE);
	}
	//计算行数
	while (EOF != (ch2 = getc(fp2)))
	{
		if ('\n' == ch2)
		{
			++rows2;
		}
	}
	rewind(fp2);
	//计算第一行的字符数
	while ('\n' != (ch2 = getc(fp2)))
	{
		++first_line_len2;
	}
	//让句柄偏移到第二行
	fseek(fp2, first_line_len2 + 1, SEEK_SET);
	int index2 = 0;
	int valid_line_num2 = 0;//读取的行数
	while (line2 < rows2)
	{
		read_line(fp2, line2_buf, size2); //读出每一行
		valid_line_num2 += parse_line(line2_buf, &(stu2[index2]));//把每一行写入结构体
		++line2;
		++index2;
	}
	InitializeList(&student2);//初始化链表;
	for (int z = 0; z < valid_line_num2; z++)
	{
		AddItem(&student, &stu2[z]);
	}
	printf("show the information of file2: \n");
	//Showstudent(temp2, &student);
	calculate_total_grade( &student);//合并后计算总分
	printf("print combine file: \n");
	//Showstudent(temp, &student);
	Sort(&student);//排序
	printf("sort from high to low:\n");
	Showstudent(temp, &student);
	//单链表逆序打印
	Node* NewList = PrintReverse(&student);
	printf("sort from low to high:\n");
	Showstudent(temp, &NewList);

	//双向链表逆序打印
	//创建一个双向链表
	student = NULL;
	DListInitializeList(&student);
	for (int z = 0; z < valid_line_num; z++)
	{
		DListAddItem(&student, &stu[z]);
	}
	printf("Dlist:\n");
	DShowstudent(temp, &student);
	for (int z = 0; z < valid_line_num2; z++)
	{
		DListAddItem(&student, &stu2[z]);
	}
	printf("Dlist combine:\n");
	DShowstudent(temp, &student);
	Dcalculate_total_grade(temp, &student);//合并后计算总分
	//排序
	DSort(&student);
	printf("sort from high to low:\n");
	DShowstudent(temp, &student);
	//逆序打印
	DPrintReverse(temp, &student);
	printf("Dsort from low to high:\n");
	Showstudent(temp, &student);
	int DelineGrade = 0;
	printf("Input the lowest number:");
	scanf("%d", &DelineGrade);
	EraseStudent(&student, DelineGrade);
	printf("more than %d:\n",DelineGrade);
	Showstudent(temp, &student);
	WriteF(temp, &student);

	ListDestroy(&student2);
	ListDestroy(&student);
	fclose(fp);
	fclose(fp2);
	free(file1_buf);
	file1_buf = NULL;
	free(file2_buf);
	file2_buf = NULL;
	free(line_buf);
	line_buf = NULL;
	free(line2_buf);
	line2_buf = NULL;
	system("pause");
	return 0;
}
//list.c
#include"count_grade.h"
#include<assert.h>
#include<stdio.h>
#include<string.h>

//链表初始化,创建空链表
void InitializeList(List *ppFirst)
{
	*ppFirst = NULL;
	return;
}

//尾插添加学生信息
CopyToItem(Node* pNode, Item *item)
{
	//pNode->item = item;
	int size = sizeof(Item);
	memcpy(&(pNode->item), item, size);
}
void AddItem(List *ppFirst, Item *item)
{
	Node* pNewNode = NULL;
	Node* pCur = *ppFirst;
	int size = sizeof(Node);
	pNewNode = (Node *)malloc(sizeof(Node));
	memset(pNewNode, 0x0, sizeof(Node));
	if (NULL == pNewNode)
	{
		printf("Fail to malloc the size\n");
		exit(EXIT_FAILURE);
	}
	CopyToItem(pNewNode, item);
	pNewNode->next = NULL;

	if (pCur == NULL)
	{
		*ppFirst = pNewNode;//链表为空,把新开辟的空间放在链表头
	}
	else
	{
		while (pCur->next != NULL)
		{
			pCur = pCur->next;
		}
		pCur->next = pNewNode;
	}
	return;
}
//打印学生信息
void Showstudent(Item item, List *ppFirst)
{
	Node *pNode = *ppFirst;
	for (pNode = *ppFirst; pNode != NULL; pNode = pNode->next)
	{
		printf("%d,%s, %s, %d, %d, %d,%d->\n", pNode->item.number, pNode->item.sex,
			pNode->item.name, pNode->item.chinese_grade,
			pNode->item.math_grade, pNode->item.english_grade, pNode->item.total_grade);
	}
	return;
 }
//计算每个学生的总分
void calculate_total_grade(List *ppFirst)
{
	Node *pNode = *ppFirst;
	for (pNode = *ppFirst; pNode; pNode = pNode->next)
	{
		int total_grade = 0;
		total_grade = pNode->item.chinese_grade + pNode->item.math_grade + pNode->item.english_grade;
		pNode->item.total_grade = total_grade;
		printf("the id is %d:the total_grade of %s is %d\n", pNode->item.number, pNode->item.name, total_grade);
	}
	return;
}

void swap(Node* p1, Node* p2)
{
	Node* p3 = p2->next;
	p1->next = p3;
	p2->next = p1;
}
void swap2(Node* p0,Node* p1, Node* p2)
{
	Node* p3 = p2->next;
	p1->next = p3;
	p2->next = p1;
	p0->next = p2;
}
void Sort(List *ppFirst)
{
	Node* pPre = NULL;
	Node* pCur = NULL;
	Node* first = NULL;
	Node* second = NULL;
	Node* pTail = NULL;

	while (pCur != pTail)
	{
		first = *ppFirst;
		second = (*ppFirst)->next;

		if ((first->item.total_grade) < (second->next->item.total_grade))
		{
			swap(pCur, pCur->next);
			*ppFirst = pCur->next;
		}
		
		pCur = second;
		pPre = first;
		while (pCur->next != pTail)
		{
			if ((pCur->item.total_grade) < (pCur->next->item.total_grade))
			{
				swap2(pPre,pCur, pCur->next);
				continue;
			}
			pCur = pCur->next;
			pPre = pPre->next;
		}
		pTail = pCur;//把tail重新指向NULL
		pCur = *ppFirst;
	}
	return;
}
#if 0
void BubbleSort(Item item, List *ppFirst)
{
	Node* pCur = NULL;
	Node* pTail = NULL;
	pCur = *ppFirst;
	while (pCur != pTail)
	{
		while (pCur->next != pTail)
		{
			if ((pCur->item.total_grade) < (pCur->next->item.total_grade))
			{
				Item temp = pCur->item;
				pCur->item = pCur->next->item;
				pCur->next->item = temp;
			}
			pCur = pCur->next;
		}
		pTail = pCur;//把tail重新指向NULL
		pCur = *ppFirst;
	}
	return;
}
#endif

//void ListPopFront(List *ppFirst,Item item)
//{
//	//开辟新空间并且写入item
//	Node *pNewNode = NULL;
//	pNewNode = (Node *)malloc(sizeof(Node));
//	memset(pNewNode, 0x0, sizeof(Node));
//	if (NULL == pNewNode)
//	{
//		printf("Fail to malloc the size\n");
//		exit(EXIT_FAILURE);
//	}
//	CopyToItem(pNewNode, &item);
//	pNewNode->next = NULL;
//	//头插
//	pNewNode->item = item; //b
//	pNewNode->next = *ppFirst; //a point
//	*ppFirst = pNewNode;//更新头结点
//
//	return;
//}
//void ListPushFront(List *ppFirst)
//{
//	Node *pCur = *ppFirst;
//	*ppFirst = pCur->next;
//	free(pCur);
//}


//逆序打印
Node* PrintReverse( List *ppFirst)
{
	Node* pCur = *ppFirst;

	Node* new_list_head = (Node*)malloc(sizeof(Node));
	new_list_head->next = NULL;
	new_list_head->item = pCur->item;

	while (NULL != pCur->next)
	{
		Node *new_node = (Node*)malloc(sizeof(Node));

		new_node->item = pCur->next->item;
		new_node->next = new_list_head;
		new_list_head = new_node;
		pCur = pCur->next;
	}
	return new_list_head;
}

//销毁链表
void ListDestroy(List *ppFirst)
{
	assert(ppFirst != NULL);

	Node *pNode = *ppFirst;
	Node *pNext = NULL;

	while (pNode != NULL)
	{
		pNext = pNode->next;//用一个变量记录下一个结点
		free(pNode);//释放当前结点
		pNode = pNext;//更新结点
	}
	*ppFirst = NULL; //释放头指针
	return;
}
//Dlist.c

#include "count_grade.h"

void DListInitializeList(List* ppFirst)
{
	*ppFirst = NULL;
	return;
}

CopyToDItem(Node* pNode, struct student* item)
{
	int size = sizeof(Item);
	memcpy(&(pNode->item), item, size);
}
void DListAddItem(List *ppFirst, struct student *stu)
{
	Node* pNewNode = NULL;
	Node* pCur = *ppFirst;
	pNewNode = (Node *)malloc(sizeof(Node));
	memset(pNewNode, 0x0, sizeof(Node));
	if (NULL == pNewNode)
	{
		printf("Fail to malloc the size\n");
		exit(EXIT_FAILURE);
	}
	CopyToDItem(pNewNode, stu);
	//尾插
	if (pCur == NULL)
	{
		//链表为空,把新开辟的空间放在链表头
		*ppFirst = pNewNode;
		pNewNode->next = NULL;
		pNewNode->pre = NULL;

	}
	else
	{
		while (pCur->next != NULL)
		{
			pCur = pCur->next;

		}
		pNewNode->next = pCur->next;
		pNewNode->pre = pCur;
		pCur->next = pNewNode;
	}
	return;
}

//打印学生信息
void DShowstudent(Item item, List *ppFirst)
{
	Node *pNode = *ppFirst;
	for (pNode = *ppFirst; pNode != NULL; pNode = pNode->next)
	{
		printf("%d,%s, %s, %d, %d, %d,%d<->\n", pNode->item.number, pNode->item.sex,
			pNode->item.name, pNode->item.chinese_grade,
			pNode->item.math_grade, pNode->item.english_grade, pNode->item.total_grade);
	}
	return;
}

//计算每个学生的总分
void Dcalculate_total_grade(Item item, List *ppFirst)
{
	Node *pNode = *ppFirst;
	for (pNode = *ppFirst; pNode; pNode = pNode->next)
	{
		int total_grade = 0;
		total_grade = pNode->item.chinese_grade + pNode->item.math_grade + pNode->item.english_grade;
		pNode->item.total_grade = total_grade;
		printf("the id is %d:the total_grade of %s is %d\n", pNode->item.number, pNode->item.name, total_grade);
	}
	return;
}
void Swap(Node* p1, Node* p2)
{
	Node* p4 = p2->next;
	Node* p0 = p1->pre;

	p1->next = p4;
	p2->next = p1;
	if (p4 != NULL)
	{
		p4->pre = p1;
	}
	if (p1->pre != NULL)
	{
		p0->next = p2;
	}
	p2->pre = p1->pre;
	p1->pre = p2;
}
void DSort(List *ppFirst)
{
	Node* pCur = NULL;
	Node* pTail = NULL;
	pCur = *ppFirst;
	while (pCur != pTail)
	{
		while (pCur->next != pTail)
		{
			if ((pCur->item.total_grade) < (pCur->next->item.total_grade))
			{
				Swap(pCur, pCur->next);
				continue;
			}
			pCur = pCur->next;
		}
		pTail = pCur;//把tail重新指向
		pCur = *ppFirst;
	}
	return;
}
#if 0
void DSort(Item item, List *ppFirst)
{
	Node* pCur = NULL;
	Node* pTail = NULL;
	pCur = *ppFirst;
	while (pCur != pTail)
	{
		while (pCur->next != pTail)
		{
			if ((pCur->item.total_grade) < (pCur->next->item.total_grade))
			{
				Item temp = pCur->item;
				pCur->item = pCur->next->item;
				pCur->next->item = temp;
			}
			pCur = pCur->next;
		}
		pTail = pCur;//把tail重新指向NULL
		pCur = *ppFirst;
	}
	return;
}
#endif

void ExchageNode(Node* p1, Node*p2)
{
	Node* p3 = p2->next;
	
	p1->next = p3;
	p2->next = p1;
	if (NULL != p3)
	{
		p3->pre = p1;
	}
	p2->pre = p1->pre;
	p1->pre = p2;
}
void DPrintReverse(Item item, List *ppFirst)
{
	Node* pNode = *ppFirst;
	while ((pNode->next) != NULL)
	{
		Node* pNext = pNode->next;
		ExchageNode(pNode, pNext);
		*ppFirst = pNext;//更新链表头
		while ((pNext->pre) != NULL)
		{
			ExchageNode(pNext->pre, pNext);
			*ppFirst = pNext;
		}
	}
}

#if 0
	Node *pNode = *ppFirst;
	Node *pNext = pNode->next;
	Node *pTail = NULL;

	Node *NewHeadNode = (Node*)malloc(sizeof(Node));

	NewHeadNode->item = (*ppFirst)->item;
	NewHeadNode->next = NULL;
	while (NULL != pNext)
	{
		pTail = pNext->next;
		Node *FNewNode = (Node*)malloc(sizeof(Node));
		FNewNode->item = pNext->item;
		NewHeadNode->pre=FNewNode;
		FNewNode->next = NewHeadNode;
		NewHeadNode = FNewNode;
		pNode = pNext;
		pNext = pTail;
	}
	return NewHeadNode;
}
#endif

int ListErase(List *ppFirst, Node* pPos)
{
	if (*ppFirst == pPos)
	{
		Node *pOldFirst = *ppFirst;
		*ppFirst = (*ppFirst)->next;
		(*ppFirst)->pre = NULL;
		free(pOldFirst);
		return 1;
	}

	Node *pCur = *ppFirst;
	for (pCur = *ppFirst; pCur->next != pPos; pCur = pCur->next)
	{
		;
	}
	pCur->next = pPos->next;
	pPos->next->pre = pPos->pre;
	free(pPos);
	return 0;
}
void EraseStudent(List *ppFirst, int DelineGrade)
{
	Node *pNode = *ppFirst;
	while (pNode)
	{
		if ((pNode->item.total_grade) < DelineGrade)
		{
			int ret = ListErase(ppFirst, pNode);
			if (1 == ret)
			{
				pNode = *ppFirst;
				continue;
			}
			pNode = pNode->pre;
		}
		pNode = pNode->next;

	}
	return;
}

void WriteF(Item item, List *ppFirst)
{
	Node *pNode = *ppFirst;
	FILE* fp = NULL;
	fp = fopen(" output.csv", "wb+");
	if (NULL == fp)
	{
		fprintf(stderr, "Can't open %s\n", " output.csv");
		exit(EXIT_FAILURE);
	}

	while (pNode)
	{
		fprintf(fp, "%d,%s, %s, %d, %d, %d,%d\n",
			pNode->item.number, pNode->item.sex,
			pNode->item.name, pNode->item.chinese_grade,
			pNode->item.math_grade, pNode->item.english_grade,
			pNode->item.total_grade);
		pNode = pNode->next;
	}

	//fwrite()
	fclose(fp);
	return;
}
#ifndef COUNT_GRADE_H
#define COUNT_GRADE_H
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include<stdbool.h>

#define LSIZE 100
typedef struct  student
{
	int number;
	char name[LSIZE];
	char sex[LSIZE];
	int math_grade;
	int chinese_grade;
	int english_grade;
	int total_grade;
};
typedef struct  student Item;
typedef struct node
{
	Item item;// 存放元素值
	struct node* next;//指向后继节点
	struct node* pre;
} Node; //单链表节点类型名

typedef Node* List;//该类型的指针名 

typedef struct  student2
{
	int number;
	char name[LSIZE];
	char sex[LSIZE];
	int math_grade;
	int chinese_grade;
	int english_grade;
};


void read_line(FILE* fp, char* line_buf, int size);
int parse_line(char *line_buf, struct student *stu);
//void calculate_total_grade(struct student *stu, int rows);


//创建一个List类型的变量。List student;
//创建一个Item类型的变量。 Item temp;
//初始化链表为空。 
//在链表末尾添加项。
//访问链表中的每个项并显示它们。
//释放分配的内存
void InitializeList(List *ppFirst);//初始化链表;
void AddItem(List *ppFirst, Item *item);
void Showstudent(Item item, List *ppFirst);
void calculate_total_grade(List *ppFirst);
void Sort(List *ppFirst);
Node* PrintReverse(List *ppFirst);
void ListDestroy(List *ppFirst);

void DListInitializeList(List* ppFirst);
void DListAddItem(List *ppFirst, struct student *stu);
void DShowstudent(Item item, List *ppFirst);
void Dcalculate_total_grade(Item item, List *ppFirst);
void DSort(List *ppFirst);
void DPrintReverse(Item item, List *ppFirst);
void EraseStudent(List *ppFirst, int DelineGrade);
void WriteF(Item item, List *ppFirst);






#endif
#include "count_grade.h"
#include <stdio.h>
#include <stdlib.h>
#include<string.h>

void read_line(FILE* fp, char* line_buf, int size)
{
	memset(line_buf, 0, size + 1);
	fgets(line_buf, size, fp);//获取一行的字符
	return;
}

int parse_line(char *line_buf, struct student *stu)
{
	//%[^a]:表示取到指定字符为止的字符串
	int  num = sscanf(line_buf, "%d,%[^,],%[^,],%d,%d,%d",
		&(*stu).number, (*stu).name, (*stu).sex, &(*stu).math_grade, &(*stu).chinese_grade, &(*stu).english_grade);
	if (num == 6)
	{
		//printf("%d,%s,%s,%d,%d,%d\n", stu->number, stu->name, stu->sex, stu->math_grade,
		//stu->chinese_grade, stu->english_grade);
		return 1;
	}
	return 0;
}


#if 0
void calculate_total_grade(struct student *stu, int rows)
{

	int total_grade = 0;
	//stu[i].chinese_grade
	total_grade = stu->chinese_grade + stu->math_grade + stu->english_grade;
	printf("the id is %d:the total_grade of %s is %d\n", stu->number, stu->name, total_grade);
	return;
}
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值