C语言程序设计:通讯录程序设计

通讯录
1. 设计要求:
通讯录至少应该有以下数据项:姓名,地址,手机,邮编,E-mail。
对通讯录应该包含有以下操作:向通讯录中添加信息,在通讯录中按姓名查找个人信息,删除通讯录中的个人信息,按不同数据项排序后列表输出通讯录中所有人的信息。通讯录中记录的数量可以是有限制的。
程序的主界面如下:
通讯录
1. 添加
2. 查询
3. 删除
4. 排序
5. 全部输出
0. 退出

2. 提高水平
在通讯录中增加将数据写入文本文件和从文件读入通讯录的功能,文件名由用户输入。
3. 提示
在没有使用文件时,通讯录数据可以保存在一个大的数组中,上面列出的数据项应该是字符串类型。

且求 详细设计说明书的编写范例
格式如下

F.1程序系统的结构
用一系列图表列出本程序系统内的每个程序(包括每个模块和子程序)的名称、标识符。
F.2程序1(标识符)设计说明
从本章开始,逐个地给出各个层次中的每个程序的设计考虑。以下给出的提纲是针对一般情况的。 对于一个具体的模块,尤其是层次比较低的模块或子程序,其很多条目的内容往往与它所隶属的上一层 模块的对应条目的内容相同,在这种情况下,只要简单地说明这一点即可。
F.2.1程序描述
给出对该程序的简要描述,主要说明安排设计本程序的目的意义,并且,还要说明本程序的特点(如 是否有返回值等)。
F.2.2功能
说明该程序应具有的功能,可采用输入——处理——输出的形式。
F.2.3性能
说明对该程序的全部性能要求,包括对精度、灵活性和时间特性的要求。
F.2.4输人项
给出对每一个输入项的特性,包括名称、标识、数据的类型和格式、数据值的有效范围、输入的方式。 数量和频度、输入媒体(例如键盘,文件等)、输入数据的来源和安全保密条件等等。
F. 2. 5输出项
给出对每一个输出项的特性,包括名称、标识、数据的类型和格式,数据值的有效范围,输出的形式、 数量和频度,输出(例如显示器,文件等)、对输出图形及符号的说明、安全保密条件等等。
F.2.6算法
详细说明本程序所选用的算法,具体的计算公式和计算步骤。
F.2.7流程逻辑
用图表(流程图)辅以必要的说明来表示本程序的逻辑流程。
F.2.8接口
用图示的形式说明本程序所隶属的上一层模块及隶属于本程序的下一层模块、子程序,说明参数赋值和调用方式,说明与本程序相直接关联的数据结构(结构体等)。
F.2.9存储分配
根据需要,说明本程序的存储分配设计。
F.2.10注释设计
说明准备在本程序中安排的注释,如:
a. 加在模块首部的注释;
b.加在各分枝点处的注释; 对各变量的功能、范围、缺省条件等所加的注释;
d.对使用的逻辑所加的注释等等。
F.2.11限制条件
说明本程序运行中所受到的限制条件。
F.2.12测试计划
说明对本程序进行单体测试的计划,包括对测试的技术要求、输入数据、预期结果等。

第1个回答  2010-07-06
#include "stdlib.h"
#include "string.h"
#include "conio.h"
#include "stdio.h"
#include "dos.h"
FILE *fp;
int i; //i是全局变量 可代替length
struct address
{ char postnum[10];
char a[40]; //家庭地址
};
struct birthday
{ int year;
int month;
int day;
};
struct ffriend
{ int num; //序号
char name[20];
char sex;
char telephone[13];
struct birthday birthday;
struct address address;

}
friends[50];

void Load()
{
int j;
long k;
fp=fopen("friend.txt","a+"); //打开文件friend.txt
if(fp!=NULL)
{
for(i=1;i<50;i++)

{
j=fgetc(fp);
if(j==EOF) //判断是否到了文件尾
return;
k=i-1;
fseek(fp,k*sizeof(struct ffriend),SEEK_SET);
fread(&friends[i],sizeof(struct ffriend),1,fp); //从文件中读取一条记录
}

}
else
{
fp=fopen("friend.txt","w");
i=1;
}

}
void Show(int j)
{
// friends[j].num=i;
printf("\n\n\t编号-Nnumber: %3d",friends[j].num);
printf("\n\t姓名-Name:%-20s",friends[j].name);
printf("\n\t性别-Sex:%c",friends[j].sex);
printf("\n\t联系电话-Telephone:%-13s",friends[j].telephone);
printf("\n\t出生日期-Birthday:%4d-%2d-%3d",friends[j].birthday.year,friends[j].birthday.month,friends[j].birthday.day);
printf("\n\t邮编-Postnum:%-10s",friends[j].address.postnum);
printf("\n\t通信地址-address:%-40s",friends[j].address.a);
}
void Append(int j)
{
fflush(stdin); //区内清除文件缓冲区,文件以写方式打开时将缓冲容写入文件
//stdin是一个标准FILE*(文件型指针)指向通常是用键盘的输入的输入流
friends[j].num=j;
printf("\n\t\t\t序号-Number:%d",j);
printf("\n\t\t\t姓名-Name:");
scanf("%s",friends[j].name);
fflush(stdin); //为什么没有fflush(stdin); 的效果会自动跳过呢?
printf("\t\t\t性别-Sex(m/w):"); //为什么输入汉字男女也会自动跳过联系电话呢
scanf("%c",&friends[j].sex);
printf("\t\t\t联系电话-telephone:");
scanf("%s",friends[j].telephone);
printf("\t出生日期-birthday");
printf("\n\t\t\t年份-year:");
scanf("%d",&friends[j].birthday.year);
printf("\t\t\t月份-month:");
scanf("%d",&friends[j].birthday.month);
printf("\t\t\t日-day:");
scanf("%d",&friends[j].birthday.day);
printf("\t\t\t邮编-Postnumber:");
scanf("%s",friends[j].address.postnum);
printf("\t\t\t通信地址-Address:");
scanf("%s",friends[j].address.a);
getchar();
}
void Delete()
{
int k;
printf("\n\tDelete 序号-Number:");
scanf("%d",&k);
if(k<=i)
{
for(int j=k;j<i+1;j++) /*插入位置后的元素顺序后移*/
{
strcpy(friends[j].name,friends[j+1].name); /*交换元素内容*/
friends[j].sex=friends[j+1].sex;
strcpy(friends[j].telephone,friends[j+1].telephone);
friends[j].birthday.year=friends[j+1].birthday.year;
friends[j].birthday.month=friends[j+1].birthday.month;
friends[j].birthday.day=friends[j+1].birthday.day;
strcpy(friends[j].address.postnum,friends[j+1].address.postnum);
strcpy(friends[j].address.a,friends[j+1].address.a);

}
i--;
}
else
{
printf("输入的序号太大!");
}
}
void Modify(int j)
{
Append(j);
}
void Save()
{
int j;
fp=fopen("friend.txt","w");
for(j=1;j<=i;j++)
{
fwrite(&friends[j],sizeof(struct ffriend),1,fp);
}
fclose(fp);

}

void main()
{
int j;
char grade;
char searchname[10];
Load();
i--;
do
{
printf("\t\t\t\t简易通讯录\n\n");
printf("功能选择(Function choose)\n");
printf("\1A.读取(Read)\n");
printf("\2B.增添(Append)\n");
printf("\6C.插入(Insert)\n");
printf("\5D.删除(Delete)\n");
printf("\5E.查询(Search)\n");
printf("\6F.修改(Modify)\n");
printf("\2G.保存(Save)\n");
printf("\1H.退出(Quit)\n");
printf("请选择(Choice)\n注:输入A~H的大写字母\n");
scanf("%c",&grade);
switch(grade)
//加个大写和小写 都可以啊
{
case 'A': j=1; //显示功能
while(getchar()!=0x1b&&j<=i) //增添按Esc键退出
{
Show(j++);
printf("\n请按回车键继续!");
}
if(j-1<1)
{
printf("\n\t空文档,无任何记录-Empty Note\n");
printf("\n请按回车键继续!");
getchar();

}
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
break;
case 'B': //增加功能
while(i<=50) //增加按ESC键退出的功能
{
i++;
Append(i);
printf("\t是否继续增加?y/n");
//修改 加上else if 其他就跳出或强制打印出出错
char a=getchar();
if(a=='n'||a=='N')
break;
}
if(i==51)
printf("\n\t文档已满,无法增加记录-note full");
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
getchar();
break;
case 'C':
int k;
printf("\n\t输入要插入的位置:");
scanf("%d",&k);
j=i+1;
friends[j].num=j;
for(j;j>k;j--) //插入功能
{
strcpy(friends[j].name,friends[j-1].name); //数据后移
friends[j].sex=friends[j-1].sex;
strcpy(friends[j].telephone,friends[j-1].telephone);
friends[j].birthday.year=friends[j-1].birthday.year;
friends[j].birthday.month=friends[j-1].birthday.month;
friends[j].birthday.day=friends[j-1].birthday.day;
strcpy(friends[j].address.postnum,friends[j-1].address.postnum);
strcpy(friends[j].address.a,friends[j-1].address.a);

}
Append(k);
i++;
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
break;
case 'D': //删除功能 //增添随意删除多条记录的功能
Delete();
if(i<1)
printf("\n没有记录-No records\n");
printf("\n请按回车键继续!");
getchar();
getchar();
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
break;
case 'E': //查询功能
printf("\n\t请输入要查询记录的相关姓名:"); //增添查询按列号的
scanf("%s",searchname);
for(j=1;j<=i;j++)
{
if(strcmp(searchname,friends[j].name)==0) //比较字符串
{
Show(j);
break;
}
}
if(i<1)
{
printf("\n 没有您所查询的记录-No records");
printf("\n 请按回车键继续!");
getchar();
}
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
getchar();
break;
case 'F': //修改功能 / /增添按序列号查询
printf("\n\t请输入要修改记录的相关姓名:");
gets(searchname);
scanf("%s",searchname);
for(j=1;j<=i;j++)
{
if(strcmp(searchname,friends[j].name)==0) //比较字符串
{
Modify(j);
// getchar(); //加个输出确定修改吗
}
}
if(i<1) //修改功能
{ printf("\n 没有您所要修改的记录-No records");
printf("\n 请按回车键继续!");
getchar();
getchar();
}
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
break;
case 'G':
Save(); //存盘功能
getchar();
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
break;

case 'H': //退出功能
char x;
printf("是否保存?yes/no\n");
scanf("%s",&x);
//getchar();
// getchar();
if(x=='y')
{
Save();
exit(0);
}
else
exit(0);

default:
printf("\n\t输入有误,请输入正确的序列号!");
printf("\n请按回车键继续!");
getchar();
printf("\n\t\t\t\t\t\t\t此次操作结束");
printf("\n\t------------------------------------------------------------\t\t\n");
}
}while(1);
}
第2个回答  2010-07-06
这个问题答案网上很多,这个地址就是http://wenku.baidu.com/view/92d3d138376baf1ffc4fad1a.html或#include 我也答过
#include "stdio.h" #include "stdlib.h" #include "string.h" #include "conio.h" #include "mem.h" #include "ctype.h" /#include "alloc.h" #define N 3 typedef struct z1
{
char no[11];
char name[15];
int score[N];
float sum;
float average;
int order;
struct z1 *next;
}STUDENT;

STUDENT *init();
STUDENT *create();
STUDENT *delete(STUDENT *h);
void print(STUDENT *h); /* 显示所有记录*/
void search(STUDENT *h); /*查找*/
void save(STUDENT *h); /*保存*/
STUDENT *load(); /*读入记录*/
void computer(STUDENT *h); /*计算总分和均分*/
STUDENT *insert(STUDENT *h); /*插入记录*/
void append(); /*追加记录*/
void copy(); /*复制文件*/
STUDENT *sort(STUDENT *h); /*排序*/
STUDENT *index(STUDENT *h); /*索引*/
void total(STUDENT *h); /*分类合计*/
int menu_select(); /*菜单函数*/
/******主函数开始*******/
main()
{
int i;
STUDENT *head; /*链表定义头指针*/
head=init(); /*初始化链表*/
clrscr(); /*清屏*/
for(;;) /*无限循环*/
{
switch(menu_select()) /*调用主菜单函数,返回值整数作开关语句的条件*/
{ /*值不同,执行的函数不同,break 不能省略*/
case 0:head=init();break;
case 1:head=create();break;
case 2:head=delete(head);break;
case 3:print(head);break; /*显示全部记录*/
case 4:search(head);break; /*查找记录*/
case 5:save(head);break; /*保存文件*/
case 6:head=load(); break; /*读文件*/
case 7:computer(head);break; /*计算总分和均分*/
case 8:head=insert(head); break; /*插入记录*/
case 9:copy();break; /*复制文件*/
case 10:head=sort(head);break; /*排序*/
case 11:append();break; /*追加记录*/
case 12:head=index(head);break; /*索引*/
case 13:total(head);break; /*分类合计*/
case 14:exit(0); /*如菜单返回值为14程序结束*/
}
}
}
/*菜单函数,返回值为整数*/
menu_select()
{
char *menu[]={"***************MENU***************", /*定义菜单字符串数组*/
" 0. init list", /*初始化*/
" 1. Enter list", /*输入记录*/
" 2. Delete a record from list", /*从表中删除记录*/
" 3. print list ", /*显示单链表中所有记录*/
" 4. Search record on name", /*按照姓名查找记录*/
" 5. Save the file", /*将单链表中记录保存到文件中*/
" 6. Load the file", /*从文件中读入记录*/
" 7. compute the score", /*计算所有学生的总分和均分*/
" 8. insert record to list ", /*插入记录到表中*/
" 9. copy the file to new file", /*复制文件*/
" 10. sort to make new file", /*排序*/
" 11. append record to file", /*追加记录到文件中*/
" 12. index on nomber", /*索引*/
" 13. total on nomber", /*分类合计*/
" 14. Quit"}; /*退出*/
char s[3]; /*以字符形式保存选择号*/
int c,i; /*定义整形变量*/
gotoxy(1,25); /*移动光标*/
printf("press any key enter menu......\n"); /*压任一键进入主菜单*/
getch(); /*输入任一键*/
clrscr(); /*清屏幕*/
gotoxy(1,1); /*移动光标*/
textcolor(YELLOW); /*设置文本显示颜色为黄色*/
textbackground(BLUE); /*设置背景颜色为蓝色*/
gotoxy(10,2); /*移动光标*/
putch(0xc9); /*输出左上角边框┏*/
for(i=1;i<44;i++)
putch(0xcd); /*输出上边框水平线*/
putch(0xbb); /*输出右上角边框 ┓*/
for(i=3;i<20;i++)
{
gotoxy(10,i);putch(0xba); /*输出左垂直线*/
gotoxy(54,i);putch(0xba);
} /*输出右垂直线*/
gotoxy(10,20);putch(0xc8); /*输出左上角边框┗*/
for(i=1;i<44;i++)
putch(0xcd); /*输出下边框水平线*/
putch(0xbc); /*输出右下角边框┛*/
window(11,3,53,19); /* 制作显示菜单的窗口,大小根据菜单条数设计*/
clrscr(); /*清屏*/
for(i=0;i<16;i++) /*输出主菜单数组*/
{
gotoxy(10,i+1);
cprintf("%s",menu[i]);
}
textbackground(BLACK); /*设置背景颜色为黑色*/
window(1,1,80,25); /*恢复原窗口大小*/
gotoxy(10,21); /*移动光标*/
do{
printf("\n Enter you choice(0~14):"); /*在菜单窗口外显示提示信息*/
scanf("%s",s); /*输入选择项*/
c=atoi(s); /*将输入的字符串转化为整形数*/
}while(c<0||c>14); /*选择项不在0~14之间重输*/
return c; /*返回选择项,主程序根据该数调用相应的函数*/
}
STUDENT *init()
{
return NULL;
}

/*创建链表*/
STUDENT *create()
{
int i; int s;
STUDENT *h=NULL,*info; /* STUDENT指向结构体的指针*/
for(;;)
{
info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/
if(!info) /*如果指针info为空*/
{
printf("\nout of memory"); /*输出内存溢出*/
return NULL; /*返回空指针*/
}
inputs("enter no:",info->no,11); /*输入学号并校验*/
if(info->no[0]=='@') break; /*如果学号首字符为@则结束输入*/
inputs("enter name:",info->name,15); /*输入姓名,并进行校验*/
printf("please input %d score \n",N); /*提示开始输入成绩*/
s=0; /*计算每个学生的总分,初值为0*/
for(i=0;i<N;i++) /*N门课程循环N次*/
{
do{
printf("score%d:",i+1); /*提示输入第几门课程*/
scanf("%d",&info->score[i]);
if(info->score[i]>100||info->score[i]<0)
printf("bad data,repeat input\n");
}while(info->score[i]>100||info->score[i]<0);
s=s+info->score[i];
}
info->sum=s;
info->average=(float)s/N;
info->order=0;
info->next=h;
h=info; }
return(h); /*返回头指针*/
}
/*输入字符串,并进行长度验证*/
inputs(char *prompt, char *s, int count)
{
char p[255];
do{
printf(prompt); /*显示提示信息*/
scanf("%s",p); if(strlen(p)>count)printf("\n too long! \n"); }while(strlen(p)>count);
strcpy(s,p); }
void print(STUDENT *h)
{
int i=0; /* 统计记录条数*/
STUDENT *p; /*移动指针*/
clrscr(); /*清屏*/
p=h; /*初值为头指针*/
printf("\n\n\n****************************STUDENT********************************\n");
printf("|rec|nO | name | sc1| sc2| sc3| sum | ave |order|\n");
printf("|---|----------|---------------|----|----|----|--------|-------|-----|\n");
while(p!=NULL)
{
i++;
printf("|%3d |%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n", i, p->no,p->name,p->score[0],p->score[1],
p->score[2],p->sum,p->average,p->order);
p=p->next;
}
printf("**********************************end*********************************\n");
}
/*删除记录*/
STUDENT *delete(STUDENT *h)
{
STUDENT *p,*q; /*p为查找到要删除的结点指针,q为其前驱指针*/
char s[11]; /*存放学号*/
clrscr(); /*清屏*/
printf("please deleted no\n"); /*显示提示信息*/
scanf("%s",s); /*输入要删除记录的学号*/
q=p=h; /*给q和p赋初值头指针*/
while(strcmp(p->no,s)&&p!=NULL) /*当记录的学号不是要找的,或指针不为空时*/
{
q=p; /*将p指针值赋给q作为p的前驱指针*/
p=p->next; /*将p指针指向下一条记录*/
}
if(p==NULL) /*如果p为空,说明链表中没有该结点*/
printf("\nlist no %s student\n",s);
else /*p不为空,显示找到的记录信息*/
{
printf("*****************************have found***************************\n");
printf("|no | name | sc1| sc2| sc3| sum | ave |order|\n");
printf("|----------|---------------|----|----|----|--------|-------|-----|\n");
printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n", p->no,
p->name,p->score[0],p->score[1],p->score[2],p->sum,
p->average,p->order);
printf("********************************end*******************************\n");
getch(); /*压任一键后,开始删除*/
if(p==h) /*如果p==h,说明被删结点是头结点*/
h=p->next; /*修改头指针指向下一条记录*/
else
q->next=p->next; /*不是头指针,将p的后继结点作为q的后继结点*/
free(p); /*释放p所指结点空间*/
printf("\n have deleted No %s student\n",s);
printf("Don't forget save\n");/*提示删除后不要忘记保存文件*/
}
return(h); /*返回头指针*/
}
/*查找记录*/
void search(STUDENT *h)
{
STUDENT *p; char s[15]; clrscr();
printf("please enter name for search\n");
scanf("%s",s); /*输入姓名*/
p=h; /*将头指针赋给p*/
while(strcmp(p->name,s)&&p!=NULL) /*当记录的姓名不是要找的,或指针不为空时*/
p=p->next; /*移动指针,指向下一结点*/
if(p==NULL) /*如果指针为空*/
printf("\nlist no %s student\n",s); /*显示没有该学生*/
else /*显示找到的记录信息*/
{
printf("\n\n*****************************havefound***************************\n");
printf("|nO | name | sc1| sc2| sc3| sum | ave |order|\n");
printf("|----------|---------------|----|----|----|--------|-------|-----|\n");
printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n", p->no,
p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order);
printf("********************************end*******************************\n");
}
}
/*插入记录*/
STUDENT *insert(STUDENT *h)
{
STUDENT *p,*q,*info; /*p指向插入位置,q是其前驱,info指新插入记录*/
char s[11]; /*保存插入点位置的学号*/
int s1,i;
printf("please enter location before the no\n");
scanf("%s",s); /*输入插入点学号*/
printf("\nplease new record\n"); /*提示输入记录信息*/
info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/
if(!info)
{
printf("\nout of memory"); /*如没有申请到,内存溢出*/
return NULL; /*返回空指针*/
}
inputs("enter no:",info->no,11); /*输入学号*/
inputs("enter name:",info->name,15); /*输入姓名*/
printf("please input %d score \n",N); /*提示输入分数*/
s1=0; /*保存新记录的总分,初值为0*/
for(i=0;i<N;i++) /*N门课程循环N次输入成绩*/
{
do{ /*对数据进行验证,保证在0~100之间*/
printf("score%d:",i+1);
scanf("%d",&info->score[i]);
if(info->score[i]>100||info->score[i]<0)
printf("bad data,repeat input\n");
}while(info->score[i]>100||info->score[i]<0);
s1=s1+info->score[i]; /*计算总分*/
}
info->sum=s1; /*将总分存入新记录中*/
info->average=(float)s1/N; /*计算均分*/
info->order=0; /*名次赋值0*/
info->next=NULL; /*设后继指针为空*/
p=h; /*将指针赋值给p*/
q=h; /*将指针赋值给q*/
while(strcmp(p->no,s)&&p!=NULL) /*查找插入位置*/
{
q=p; /*保存指针p,作为下一个p的前驱*/
p=p->next; /*将指针p后移*/
}
if(p==NULL) /*如果p指针为空,说明没有指定结点*/
if(p==h) /*同时p等于h,说明链表为空*/
h=info; /*新记录则为头结点*/
else
q->next=info; else
if(p==h) {
info->next=p; h=info; }
else
{
info->next=p; q->next=info;
}
printf("\n ----have inserted %s student----\n",info->name); printf("---Don't forget save---\n"); /*提示存盘*/
return(h); /*返回头指针*/
}
/*保存数据到文件*/
void save(STUDENT *h)
{
FILE *fp; /*定义指向文件的指针*/
STUDENT *p; /* 定义移动指针*/
char outfile[10]; /*保存输出文件名*/
printf("Enter outfile name,for example c:\\f1\\te.txt:\n"); /*提示文件名格式信息*/
scanf("%s",outfile);
if((fp=fopen(outfile,"wb"))==NULL) /*为输出打开一个二进制文件,如没有则建立*/
{
printf("can not open file\n");
exit(1);
}
printf("\nSaving file......\n"); /*打开文件,提示正在保存*/
p=h; /*移动指针从头指针开始*/
while(p!=NULL) /*如p不为空*/
{
fwrite(p,sizeof(STUDENT),1,fp);/*写入一条记录*/
p=p->next; /*指针后移*/
}
fclose(fp); /*关闭文件*/
printf("-----save success!!-----\n"); /*显示保存成功*/
}
/* 从文件读数据*/
STUDENT *load()
{
STUDENT *p,*q,*h=NULL; /*定义记录指针变量*/
FILE *fp; /* 定义指向文件的指针*/
char infile[10]; /*保存文件名*/
printf("Enter infile name,for example c:\\f1\\te.txt:\n"); scanf("%s",infile); /*输入文件名*/
if((fp=fopen(infile,"rb"))==NULL) /*打开一个二进制文件,为读方式*/
{
printf("can not open file\n"); /*如不能打开,则结束程序*/
exit(1);
}
printf("\n -----Loading file!-----\n");
p=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/
if(!p)
{
printf("out of memory!\n"); /*如没有申请到,则内存溢出*/
return h; /*返回空头指针*/
}
h=p; /*申请到空间,将其作为头指针*/
while(!feof(fp)) /*循环读数据直到文件尾结束*/
{
if(1!=fread(p,sizeof(STUDENT),1,fp))
break; /*如果没读到数据,跳出循环*/
p->next=(STUDENT *)malloc(sizeof(STUDENT)); /*为下一个结点申请空间*/
if(!p->next)
{
printf("out of memory!\n"); return h;
}
q=p; p=p->next; }
q->next=NULL; /*最后一个结点的后继指针为空*/
fclose(fp); /*关闭文件*/
printf("---You have success read data from file!!!---\n");
return h; /*返回头指针*/
}
/*追加记录到文件*/
void append()
{
FILE *fp; /*定义指向文件的指针*/
STUDENT *info; /*新记录指针*/
int s1,i;
char infile[10]; /*保存文件名*/
printf("\nplease new record\n");
info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/
if(!info)
{
printf("\nout of memory"); /*没有申请到,内存溢出本函数结束*/
return ;
}
inputs("enter no:",info->no,11); /*调用inputs输入学号*/
inputs("enter name:",info->name,15); /*调用inputs输入姓名*/
printf("please input %d score \n",N); /*提示输入成绩*/
s1=0;
for(i=0;i<N;i++)
{
do{
printf("score%d:",i+1);
scanf("%d",&info->score[i]); /*输入成绩*/
if(info->score[i]>100||info->score[i]<0)printf("bad data,repeat input\n");
}while(info->score[i]>100||info->score[i]<0); /*成绩数据验证*/
s1=s1+info->score[i]; /*求总分*/
}
info->sum=s1; /*保存总分*/
info->average=(float)s1/N; /*求均分*/
info->order=0; /*名次初始值为0*/
info->next=NULL; /*将新记录后继指针赋值为空*/
printf("Enter infile name,for example c:\\f1\\te.txt:\n"); scanf("%s",infile); /*输入文件名*/
if((fp=fopen(infile,"ab"))==NULL) /*向二进制文件尾增加数据方式打开文件*/
{
printf("can not open file\n"); /*显示不能打开*/
exit(1); /*退出程序*/
}
printf("\n -----Appending record!-----\n");
if(1!=fwrite(info,sizeof(STUDENT),1,fp)) /*写文件操作*/
{
printf("-----file write error!-----\n");
return; /*返回*/
}
printf("-----append sucess!!----\n");
fclose(fp); /*关闭文件*/
}
/*文件拷贝*/
void copy()
{
char outfile[10],infile[10];
FILE *sfp,*tfp; /*源和目标文件指针*/
STUDENT *p=NULL; /*移动指针*/
clrscr(); /*清屏*/
printf("Enter infile name,for example c:\\f1\\te.txt:\n");
scanf("%s",infile); /*输入源文件名*/
if((sfp=fopen(infile,"rb"))==NULL) /*二进制读方式打开源文件*/
{
printf("can not open input file\n");
exit(0);
}
printf("Enter outfile name,for example c:\\f1\\te.txt:\n"); /*提示输入目标文件名*/
scanf("%s",outfile); /*输入目标文件名*/
if((tfp=fopen(outfile,"wb"))==NULL) /*二进制写方式打开目标文件*/
{
printf("can not open output file \n");
exit(0);
}
while(!feof(sfp)) /*读文件直到文件尾*/
{
if(1!=fread(p,sizeof(STUDENT),1,sfp))
break; /*块读*/
fwrite(p,sizeof(STUDENT),1,tfp); /*块写*/
}
fclose(sfp); /*关闭源文件*/
fclose(tfp); /*关闭目标文件*/
printf("you have success copy file!!!\n"); /*显示成功拷贝*/
}
/*排序*/
STUDENT *sort(STUDENT *h)
{
int i=0; /*保存名次*/
STUDENT *p,*q,*t,*h1; /*定义临时指针*/
h1=h->next; /*将原表的头指针所指的下一个结点作头指针*/
h->next=NULL; /*第一个结点为新表的头结点*/
while(h1!=NULL) /*当原表不为空时,进行排序*/
{
t=h1; /*取原表的头结点*/
h1=h1->next; /*原表头结点指针后移*/
p=h; /*设定移动指针p,从头指针开始*/
q=h; /*设定移动指针q做为p的前驱,初值为头指针*/
while(t->sum<p->sum&&p!=NULL) /*作总分比较*/
{
q=p; /*待排序点值小,则新表指针后移*/
p=p->next;
}
if(p==q) /*p==q,说明待排序点值大,应排在首位*/
{
t->next=p; /*待排序点的后继为p*/
h=t; /*新头结点为待排序点*/
}
else /*待排序点应插入在中间某个位置q和p之间,如p为空则是尾部*/
{
t->next=p; /*t的后继是p*/
q->next=t; /*q的后继是t*/
}
}
p=h; /*已排好序的头指针赋给p,准备填写名次*/
while(p!=NULL) /*当p不为空时,进行下列操作*/
{
i++; /*结点序号*/
p->order=i; /*将名次赋值*/
p=p->next; /*指针后移*/
}
printf("sort sucess!!!\n"); /*排序成功*/
return h; /*返回头指针*/
}
/*计算总分和均值*/
void computer(STUDENT *h)
{
STUDENT *p; /*定义移动指针*/
int i=0; /*保存记录条数初值为0*/
long s=0; /*总分初值为0*/
float average=0; /*均分初值为0*/
p=h; /*从头指针开始*/
while(p!=NULL) /*当p不为空时处理*/
{
s+=p->sum; /*累加总分*/
i++; /*统计记录条数*/
p=p->next; /*指针后移*/
}
average=(float)s/i;/* 求均分,均分为浮点数,总分为整数,所以做类型转换*/
printf("\n--All students sum score is:%ld average is %5.2f\n",s,average);
}
/*索引*/
STUDENT *index(STUDENT *h)
{
STUDENT *p,*q,*t,*h1; /*定义临时指针*/
h1=h->next; /*将原表的头指针所指的下一个结点作头指针*/
h->next=NULL; /*第一个结点为新表的头结点*/
while(h1!=NULL) /*当原表不为空时,进行排序*/
{
t=h1; /*取原表的头结点*/
h1=h1->next; /*原表头结点指针后移*/
p=h; /*设定移动指针p,从头指针开始*/
q=h; /*设定移动指针q做为p的前驱,初值为头指针*/
while(strcmp(t->no,p->no)>0&&p!=NULL) /*作学号比较*/
{
q=p; p=p->next;
}
if(p==q) /*p==q, {
t->next=p; h=t; }
else {
t->next=p; /*t的后继是p*/
q->next=t; /*q的后继是t*/
}
}
printf("index sucess!!!\n"); /*索引排序成功*/
return h; /*返回头指针*/
}
/*分类合计*/
void total(STUDENT *h)
{
STUDENT *p,*q; /*定义临时指针变量*/
char sno[9],qno[9],*ptr; /*保存班级号的*/
float s1,ave; /*保存总分和均分*/
int i; clrscr(); /*清屏*/
printf("\n\n *******************Total*****************\n");
printf("---class---------sum--------------average----\n");
p=h; while(p!=NULL)
{
memcpy(sno,p->no,8); /*从学号中取出班级号*/
sno[8]='\0'; /*做字符串结束标记*/
q=p->next; /*将指针指向待比较的记录*/
s1=p->sum; /*当前班级的总分初值为该班级的第一条记录总分*/
ave=p->average; /*当前班级的均分初值为该班级的第一条记录均分*/
i=1; /*统计当前班级人数*/
while(q!=NULL) /*内循环开始*/
{
memcpy(qno,q->no,8); /*读取班级号*/
qno[8]='\0'; /*做字符串结束标记*/
if(strcmp(qno,sno)==0) /*比较班级号*/
{
s1+=q->sum; /*累加总分*/
ave+=q->average; /*累加均分*/
i++; /*累加班级人数*/
q=q->next; /*指针指向下一条记录*/
}
else
break; }
printf("%s %10.2f %5.2f\n",sno,s1,ave/i);
if(q==NULL)
break; else
p=q; }
printf("---------------------------------------------\n");
}