|
|
#8
猎豹2010-04-27 20:21
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
struct student
{
char name[20];
int year;
int month;
student *next;//下一个学生结点指针
};
int num=0;
//s表示一组学生信息链表的表头指针
void input_student(student *&s);
//采用插入法,边插入边按由大到小排序
//形参*&s表示s是一个引用指针,用于返回输入的指针值
void output_student(student *p);
//输出p为头指针的链表表示的学生信息。
void save_student(char *n,student *p);
//将以p为头指针的链表表示的学生信息保存在以字符串n为文件名的磁盘文件中
int main()
{
student *s=NULL;//s为链表头指针
cout<<"请输入一组学生数据"<<endl;
input_student(s);
cout<<"学生信息为"<<endl;
output_student(s);
cout<<"将学生信息保存在磁盘文件中,输入磁盘文件名"<<endl;
char name[20];
cin>>name;
save_student(name,s);
system("pause");
return 0;
}
void input_student(student *&s)
{
student *t;//流动结点指针,用于指向新产生的结点
cout<<"请输入学生信息"<<endl;
do
{
char name[20];
int year,month;
cout<<"学生姓名(*为终止标志):";cin>>name;
if(strcmp(name,"*")==0)break;
cout<<"学生出生年份:";cin>>year;
cout<<"学生出生月份:";cin>>month;
num++;
t=new student;
//t->name=name;
strcpy(t->name,name);
t->year=year;
t->month=month;
t->next=NULL;
//给新结点填充数据,下一项指针next置空
if(!s)//原头指针空
s=t; //新结点指针作为头指针
else
{
student *p=s;//p作为循环用的流动指针,从头指针开始
if(t->year>p->year||(t->year==p->year&&t->month>=p->month))
//t指向的结点比原来头指针指向的结点大
{
s=t;//t取代头指针s,原头指针p作为新头指针s的后继
s->next=p;
}
else
{
student *q;//设置指针q用于查找新指针t在链表中位置的前驱
while(p&&(t->year<p->year)||(t->year==p->year&&t->month<p->month))
//查找新结点应该插入的位置q之后p之前
{
q=p;
p=p->next;
}// while循环终止时,有两种情况,1,t在q和p之间直接插入
//2,t在结尾之后q指向尾结点,p空指针,将t接在q后,t接空指针
q->next=t;
t->next=p;
}
}
}while(1);//while条件永真,出口设在输入姓名“*”处
}
void output_student(student *p)
{
student *t=p;//t作为流动指针
cout<<"共有"<<num<<"个学生,从小到大排列为"<<endl;
cout<<setw(10)<<"姓名"<<setw(10)<<"出生年份"<<setw(10)<<"出生月份"<<endl;
while(t)//t不空,表示t所指向的结点存在,输出相关信息
{
cout<<setw(10)<<t->name<<setw(10)<<t->year<<setw(10)<<t->month<<endl;
t=t->next;
}
}
void save_student(char *n,student *p)
{
ofstream out(n,ios::out|ios::binary);
if(!out)
{
cout<<"磁盘文件"<<n<<"打开失败"<<endl;
system("pause");
return;
}
out.write((char*)&num,sizeof(int));
//保存学生人数,以便读文件时使用
for(student *t=p;t;t=t->next)
{
//t作为流动指针,从头指针p开始,当前结点输出之后,指针后移一项
out.write((char*)t,sizeof(student));
//第一个参数是输出数据的位置,即指针t所指结点的地址
//即&(*t),实际上就是t
//第二个参数是输出数据的长度,即输出一个结点的长度
}
out.close();
cout<<"输出结点的个数为"<<num<<endl;
}
|