/*
功能:从文件中读入数据(文件为存储学号和姓名的文本,且学号和姓名在同一行,中间有空格),排序后输出到student_mass.txt
文件名:sort.c
作者:flonlen
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/********* 定义链表结点的具体内容 ***********/
typedef struct _student
{
char stu_id[20];
char name[20];
struct _student *prov;
struct _student *next;
}student,*stu;
/********* 函数功能:初始化头结点 ***********/
void init_head(stu list)
{
list->next = list;
list->prov = list;
}
/********* 函数功能:插入结点 ***********/
void list_add(stu node,stu prov,stu next)
{
node->next = next;
node->prov = prov;
prov->next = node;
next->prov = node;
}
/****** 函数功能:将文件内容导入链表 *******/
void read_to_list(stu head)
{
FILE *fp;
int i ,j;
stu node;
char file_name[20],stu_mass[40] ,name[20];
printf("请输入要打开的文件名:");
scanf("%s",file_name);
fp = fopen(file_name,"r");
while(!feof(fp))
{
node = (stu)malloc(sizeof(student));
i = 0,j = 0;
fgets(stu_mass,40,fp);
while(stu_mass[i] != ' ')
{
i++;
j++;
}
while(stu_mass[j] == ' ')
{
j++;
}
strcpy(node->stu_id,stu_mass);
node->stu_id[i] = '\0';
i = 0;
while(name[j] != '\0')
{
name[i] = stu_mass[j];
if(name[i] == '\n')
name[i] = '\0';
j++;
i++;
}
strcpy(node->name,name);
list_add(node,head,head->next);
}
fclose(fp);
}
/*********** 函数功能:定位第i个节点 **************/
stu pos_node(stu head,int i)
{
stu temp;
int j;
temp = head->next;
for(j = i;j > 1;j--)
temp = temp->next;
return temp;
}
/****** 函数功能:节点交换 *******/
void exch_node(stu node1,stu node2)
{
stu temp1,temp2;
if(node1->next == node2)
{
temp1 = node1->prov;
temp2 = node2->next;
node1->next = temp2;
node1->prov = node2;
temp2->prov = node2;
node2->prov = temp1;
node2->next = node1;
temp1->next = node2;
}
else
if(node2->next == node1)
{
temp1 = node2->prov;
temp2 = node1->next;
node2->next = temp2;
node2->prov = node1;
temp2->prov = node2;
node1->prov = temp1;
node1->next = node2;
temp1->next = node1;
}
else
{
temp1 = node2->next;
temp2 = node2->prov;
node1->next->prov = node2;
node1->prov->next = node2;
node2->next = node1->next;
node2->prov = node1->prov;
node1->prov = temp2;
node1->next = temp1;
temp1->prov = node1;
temp2->next = node1;
}
}
/******* 函数功能:排序 *******/
void sort(stu head)
{
stu temp;
int num = 0,i,j;
double jindu;
long jishu=0;
temp = head->next;
while(temp != head)
{
num++;
temp = temp->next;
}
printf("排序中,请稍后。。。\n");
for(i = 1;i < num+1;i++)
{
jindu = ((double)(i+1))/num;
printf("\r已完成:%.1lf%%",jindu*100); //排序进度
for(j = i;j < num+1;j++)
{
if(strcmp(pos_node(head,i)->stu_id,pos_node(head,j)->stu_id) > 0)
{
exch_node(pos_node(head,j),pos_node(head,i));
}
}
}
printf("完成排序。\n");
}
/********** 函数功能:排序输出到文件 ***********/
void write_to_txt(stu head)
{
FILE *fp;
stu temp;
temp = head->next;
fp = fopen("student_mass.txt","w+");
while(temp != head)
{
fwrite(temp->stu_id,strlen(temp->stu_id),1,fp);
fputc(' ',fp);
fwrite(temp->name,strlen(temp->name),1,fp);
fputc('\n',fp);
temp = temp->next;
}
fputc('\n',fp);
fclose(fp);
}
/********* 函数功能:查找学生信息并输出该学生的具体信息 ***********/
void search_stu(stu head)
{
char act,sea_mass[20];
stu temp;
getchar();
temp = head->next;
ACTION:
printf("按姓名查找请输入1,按学号查找请输入2,退出请输入3:");
act = getchar();
if(act == '1')
{
printf("请输入要查找的姓名:");
scanf("%s",sea_mass);
getchar();
while(strcmp(temp->name,sea_mass) != 0)
{
temp = temp->next;
if(temp == head)
{
printf("没找到该学生,请检查是否输入有误!\n");
goto ACTION;
}
}
}
else
if(act == '2')
{
printf("请输入要查找的学号:");
scanf("%s",sea_mass);
getchar();
while(strcmp(temp->stu_id,sea_mass) != 0)
{
temp = temp->next;
if(temp == head)
{
printf("没找到该学生,请检查是否输入有误!\n");
goto ACTION;
}
}
}
else
if(act == '3')
{
exit(0);
}
else
{
printf("输入错误,请重新输入。\n");
goto ACTION;
}
printf("姓名:%s,学号:%s\n",temp->name,temp->stu_id);
goto ACTION;
}
/****** 主函数 *******/
int main(int argc,char *argv[])
{
stu head;
head = (stu)malloc(sizeof(student));
init_head(head);
read_to_list(head);
sort(head);
write_to_txt(head);
search_stu(head);
return 0;
}