程序设计实训专题讲座

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、程序设计训练目的和教学要求
“C程序设计训练”是在学习“C语言程序设计”课程之后进行的一个实践教学环节,程序设计训练的目的是:
1.进一步培养学生结构化程序设计的思想,加深对高级语言基本语言要素和控制结构的理解;
2.针对C语言中的重点和难点内容进行训练,独立完成有一定工作量的程序设计任务,同时强调好的程序设计风格。

3.掌握C语言的编程技巧和上机调试程序的方法。

4.掌握程序设计的常用算法及模块化程序设计方法。

5. 掌握项目与工程设计的基本方法。

本程序设计训练是利用C语言理论和实验课中学到的编程知识和编程技巧,通过布置具有一定难度、一定编程量的程序设计训练题目,使学生通过程序设计训练掌握高级编程语言的知识和编程技术,掌握程序设计的思想和方法,具备利用计算机求解实际问题的能力。

二、程序设计训练的基本要求
设计步骤的规范不但可以培养学生科学的工作方法和作风,而且还能有效地减少错误,提高工作效率。

因此必须严格执行良好的实验步骤规范(包括上级操作规范)。

本程序设计训练的基本步骤与要求是:
1.问题分析及解决方案框架确定
●充分地分析和理解问题本身,弄清要求做什么(What to do?)。

●在确定解决方案框架过程中(How to do?),考虑怎样使程序结构清晰、合
理、简单和易于调试,并确定每个函数的简单功能,以及函数之间的调用关
系。

2.详细设计和编码
确定算法的主要流程,再此基础上进行代码设计(Coding),每个明确的功能模块程序一般不超过60行,否则要进一步划分。

3.上机前编写程序与检查
上机前程序检查可有效提高调试效率,减少上机调试程序时的无谓错误。

程序检查主要有两种途径:用一组测试数据手工执行程序;通过阅读或给别人讲解自己的程序而深入全面地理解程序逻辑,把程序中的明显错误事先排除。

4.上机调试程序
5.完成程序设计训练报告
①问题描述:题目要解决的问题是什么。

②设计
●设计算法:主要算法思想,用流程图表示。

●实现注释:各项功能的实现程度。

●调试报告:调试过程中遇到的主要问题,是如何解决的;对设计和编码的回
顾讨论和分析;改进设想;经验和体会等。

③如果题目规定了测试数据,则结果要包含这些测试数据和运行输出,当然还可以含其他测试数据和运行输出。

三、程序设计训练的内容
见程序设计训练题目(共8题)。

要求都能编写程序和运行,但验收时,1~5题中任抽一道题,6~8题中任抽一道题,并提交所抽中的两题的实验报告。

四、程序设计训练安排
1、课堂教学(1周,8学时)。

用于讲授程序设计的方式方法,包括原问题的分析、算法设计、程序编写以及调试等,内容从基本程序设计到项目的实现,以及程序设计文档的编制方法。

a) 程序设计的基本方法
b) 程序代码的规范(最佳实践法)
c) 工程方法论
d) 项目实践
2、训练辅导(2周,20学时)(8月24号~下学期开学
现场辅导:以2个自然班为教学班,每天2课时现场辅导,每教学班一名教师配一名助教。

3、测试(1周,4学时)
学生从3类(见训练内容)题中,各选择一道,提前写好设计训练报告,现场编写(断网、断U盘)程序,独立完成,根据完成情况予以评分。

五、考核方式与评分办法
通过程序实现、总结报告和学习态度综合考评,并结合学生的动手能力,独立分析解决问题的能力和创新精神。

成绩分优、良、中、及格和不及格五等。

考核标准包括:
1.程序设计的正确性,程序结构是否合理、编程风格(50%)。

2.学生的工作态度、动手能力、创新精神及出勤率(30%)。

3.总结报告(20%)。

六、程序设计报告的封面
程序设计基础课程实训题目:
院系:
专业班级:
姓名:
学号:
指导老师:
七、训练报告的格式
一、目的和要求
二、设计内容
三、运行环境
四、设计步骤
五、流程图
六、源代码
七、运行结果
八、总结
八、部分训练题目算法分析
1、日历问题
问题描述
在我们现在使用的日历中, 闰年被定义为能被4整除的年份,但是能被100整除而不能被400整除的年是例外,它们不是闰年。

例如:1700, 1800, 1900 和 2100 不是闰年,而 1600, 2000 和 2400是闰年。

给定从公元2000年1月1日开始逝去的天数,你的任务是给出这一天是哪年哪月哪日星期几。

输入数据
输入包含若干行,每行包含一个正整数,表示从2000年1月1日开始逝去的天数。

输入最后一行是−1, 不必处理。

可以假设结果的年份不会超过9999。

输出要求
对每个测试样例,输出一行,该行包含对应的日期和星期几。

格式为“YYYY-MM-DD DayOfWeek”, 其中“DayOfWeek” 必须是下面中的一个: "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" and "Saturday“。

(1)确定某年的第一天是星期几?
int day(int year)//求某年的第一天是星期几
{long a,b;
if(year<=2000)
{a=2000-year;b=6-(a+a/4-a/100+a/400)%7; return b;
}
else {a=year-2000; b=(a+1+(a-1)/4-(a-1)/100+(a-1)/400)%7+6;
return b%7;
}
}
(2)求出2000年1月1日是星期几
Y=day(2000)
(3)求从2000年1月1日开始逝去的天数days除以7的余数
Z=days%7
(4)求days是星期几
x=(y+z)%7
(5)利用字符数组输出下标x所对应的星期英文名(6)求days的年月日
Year=2000 month=1 day=1
利用循环while(days){days--;day++…}
如果day达到某月的最后一天,day=1,month++
如果month=12,day=31,则year++,month=1,day=1
但要考虑闰年问题
2、生理周期
问题描述
人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23 天、28 天和33 天。

每一个周期中有一天是高峰。

在高峰这天,人会在相应的方面表现出色。

例如,智力周期的高峰,人会思维敏捷,精力容易高度集中。

因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天。

对于每个人,我们想知道何时三个高峰落在同一天。

对于每个周期,我们会给出从当前年份的第一天开始,到出现高峰的天数(不一定是第一次高峰出现的时间)。

你的任务是给定一个从当年第一天开始数的天数,输出从给定时间开始(不包括给定时间)下一次三个高峰落在同一天的时间(距给定时间的天数)。

例如:给定时间为10,下次出现三个高峰同天的时间是12,则输出2(注意这里不是3)。

输入数据
输入四个整数:p, e, i 和d。

p, e, i 分别表示体力、情感和智力高峰出现的时间(时间从当年的第一天开始计算)。

d 是给定的时间,可能小于p, e, 或 i。

所有给定时间是非负的并且小于365, 所求的时间小于等于21252。

输出要求
从给定时间起,下一次三个高峰同天的时间(距离给定时间的天数)。

解题思路:假设从当年的第一天开始数,第x天三个高峰值同时出现,符合要求的x必须在[d+1,21252]之间,并且同时满足三个条件(1)(x-p)%23==0
(2)(x-e)%28==0 (3)(x-i)%33==0
于是可以用三种方法解决问题。

方法一slzq.c:
(1)设置数组m表示三个周期的长度
int m[3]={23,28,33}
(2)设置数组a表示体力、情感和智力高峰出现的时间
从键盘输入a
(3)计算出三者高峰同时出现的时间
ans=0;
for(j=0;j<3;j++)
{ int t=M/m[j];
ext_gcd(t,m[j]);
ans=(ans+t*x*a[j])%M;
}
其中:M=m[0]*m[1]*m[2]
t=M/m[i], i=0,1,2
x由下面函数求出
(4)设置全局变量x,y
int x,y;
void ext_gcd(int a,int b)
{ int t;
if(b==0) { x=1; y=0; }
else { ext_gcd(b,a%b);
t=x; x=y; y=t-a/b*y; }}
(5)调用ext_gcd(t,m[i]),求出x
(6)a ns<d执行下面循环
while(ans<=d)
{ ans+=M;
}
(7)a ns-d为所求的结果(d为给定的时间,从键盘输入)
方法二slzq1.c:
a[0],a[1],a[2]分别代表p,e,i,表示体力、情感、智力出现最大值的时间m[0],m[1],m[2]分别表示三个的周长
M=1;
for(j=0;j<3;j++) M*=m[j];
for(j=d+1;j<=M;j++)
if((j-a[0])%m[0]==0)break;
for(;j<=M;j=j+m[0])
if((j-a[1])%m[1]==0) break;
for(;j<=M;j=j+m[0]*m[1])
if((j-a[2])%m[2]==0)
方法三slzq2.c
M=m[0]*m[1]*m[2];
for(j=d+1;j<=M;j++)
{x=(j-a[0])%m[0]==0;
y=(j-a[1])%m[1]==0;
z=(j-a[2])%m[2]==0;
if(x&&y&&z)printf(“%d\n”,j-d);
3、约瑟夫问题
问题描述
约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再从出圈的下一个开始报数。

就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入数据
每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m, n < 300)。

最后一行
是:
0 0
输出要求
对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号(1)选用所用的解决问题的方法
可以使用数组、循环链表、结构数组
(2)用数组解决问题
建立一个一维数组a,a[1]~a[n]存放n个人的编号,对n个人按1,2,…,m的顺序报数,报数为m的人保存到a[0]中,后面的人往前移动一个位置,报数的人数减1,再重复下去,最后a[1]中的值就是所求的值。

s1=1;
for(i=n;i>=2;i--)
{s1=(s1+m-1)%i;
if(s1==0) s1=i;
w=a[s1];
for(j=s1;j<i;j++)
a[j]=a[j+1];
a[i]=w;
(3)用循环链表解决问题
将n个人的编号建立一个循环链表,通过报数,删除要离开的结点,当链表中剩下一个结点时,即为所求的值。

(4)用结构数组解决问题
struct monkey
{ int no; //猴子编号
int next; //下一个猴子编号
};
struct monkey link[N];//n个猴子信息
count=0; //出圈人数
h=n;
while(count< n-1)
{ i=0;
while(i!=m)
{h=link[h].next;
if(link[h].no) i++;}
link[h].no=0;count++;//离开的猴子值为0,数目加1
}
最后结构中值不为0的即为所求的值。

4、恺撒Caesar密码
题目描述
Julius Caesar 生活在充满危险和阴谋的年代。

为了生存,他首次发明了密码,用于军队的消息传递。

假设你是Caesar 军团中的一名军官,需要把Caesar 发送的消息破译出来、并提供给你的将军。

消息加密的办法是:对消息原文中的每个字母,分别用该字母之后的第5个字母替换(例如:消息原文中的每个字母A都分别替换成字母F),其他字符不变,并且消息原文的所有字母都是大写的。

密码字母:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
原文字母:V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
输入数据
最多不超过100个数据集组成。

每个数据集由3部分组成:
起始行:START
密码消息:由1到200个字符组成一行,表示Caesar发出的一条消息
结束行:END
在最后一个数据集之后,是另一行:ENDOFINPUT
输出要求
每个数据集对应一行,是Caesar 的原始消息。

(1)输入字符串密码
(2)解密
是字母,则key值减5,减5后若不是字母,加26
#define isletter( c ) ( ((c)>='a'&&(c)<='z') ||
((c)>='A'&&(c)<='Z') )
void Denc( const char *str, char *out, int key )
{ int i=0;
while( str[i] )
{
if ( isletter( str[i] ) )
{ out[i] = str[i] - key;
if ( ! isletter( out[i] ) )
out[i] += 26;
}
else
out[i] = str[i];
i++;
}
out[i] = 0;
}
5、身份证校验
题目描述
我国国标〖GB 11643-1999〗中规定:公民身份号码是18位特征组合码,由十七位数字本体码和一位数字校验码组成。

排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

其校验码(最后一位)计算方法和步骤为:
(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
其中Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子,前17位加权因子从左到右分别为
Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(2)计算模
Y = mod(S, 11)
(3)通过模Y查下表得到对应的校验码
查(3)得校验码为x
请按上面所述步骤编程,输入一个二代身份证号,检查该身份证是否正确。

(1)将输入的十八位身份证保存到一个一维数组b中
(2)设定十七位权值保存到数组d中(题目中给定)
(3)利用s=b[1]*d[1]+b[2]*d[2]+…+b[17]*d[17]求权值和
但注意字符b要转换成整型
(4)n=s%11求出数组y的下标
(5)利用数组y保存校验码
(6)Y[n]=b[18]身份证正确,否则身份证不正确
6、学生成绩管理
学生信息包括:学号、姓名、年龄、性别、出生年月。

主要功能:
(1)能按学期、按班级完成对学生成绩的录入、修改。

(2能按班级统计学生的成绩,求学生的总分及平均分,并能根据学生的平均成绩进行排序。

(3)能查询学生成绩。

(4)能按班级输出学生的成绩单。

用键盘菜单程序的实现
(1)将各功能写成菜单形式
printf("\n欢迎使用学生成绩管理系统系统\n");
1.printf("1. 录入 \n");
2.printf("2. 修改 \n");
3.printf("3. 统计 \n");
4.printf("4. 查询 \n");
5.printf("5. 打印 \n");
6.printf("6. 退出 \n");
(2)利用switch执行相应的自定义函数
scanf("%d",&op);
switch(op)
{ case 1:a1();ch='Y';break; //录入
case 2:a2();ch='Y';break; //修改
case 3:a3();ch='Y';break; //统计
case 4:a4();ch='Y';break; //查询
case 5:a5();ch='Y';break; //打印成绩单
default:ch='N';break;
}
(3)利用循环重复1、 2、两步
main()
{ int op;char ch;
do
{
system("cls");
printf("\n欢迎使用学生成绩管理系统系统\n");
printf("1. 录入 \n");
printf("2. 修改 \n");
printf("3. 统计 \n");
printf("4. 查询 \n");
printf("5. 打印 \n");
printf("6. 退出 \n");
scanf("%d",&op);
switch(op)
{ case 1:a1();ch='Y';break;
case 2:a2();ch='Y';break;
case 3:a3();ch='Y';break;
case 4:a4();ch='Y';break;
case 5:a5();ch='Y';break;
default:ch='N';break;
}
}while(ch=='Y');
(4)各自定义函数单独完成
//录入学生成绩
void a1()
{ system("cls");
printf("录入学生成绩\n");
……
getch();}
//修改学生成绩
void a2()
{ system("cls");
printf("修改学生成绩\n");
……
getch();}
//统计学生成绩
void a3()
{ system("cls");
printf("统计学生成绩\n");
……
getch();}
//查询学生成绩
void a4()
{ system("cls");
printf("查询学生成绩\n");
……
getch();}
//打印成绩单
void a5()
{ system("cls");
printf("打印成绩单\n");
……
getch();}
(5)确定所使用的存储结构
可以使用数组,也可以使用链表
(6)假设采用数组作存储结构
#define N 100 //一个班的人数struct student
{ long xq; //学期
char bj[20]; //班级
char xh[20]; //学号
char xm[20]; //姓名
char xb[8]; //性别
long csny; //出生年月
float cj[6]; //6门成绩
float total; //总分
float aver; //平均分
};
struct student x[N]; //N个学生
long xueqi; //学期
char banji[20]; //班级
int n; //一个班的实际人数
7、学生成绩管理文件结构
(1)先用记事本编辑文件stu1.dat存储一个班学习成绩。

然后在C环境下,建立一个学生信息的结构体,用r方式打开上述文件,再用fscanf读入、用printf在屏幕上显示文件内容。

(2)利用循环使每个学生的三门功课的成绩相加,然后再把和除以三就得到了平均成绩。

接着用冒泡法利用平均分的高低排出名次。

最后用fprintf将每个学生的信息写入到stu2.dat文件。

(1)定义结构表示学生信息
struct student
{ long xq; //学期
char bj[20]; //班级
char xh[20]; //学号
char xm[20]; //姓名
char xb[8]; //性别
long csny; //出生年月
float cj[3]; //3门成绩
float total; //总分
float aver; //平均分
};
struct student x[N];
(2)用记事本建立文件stu1.dat
包含一个班学生成绩
(3)打开文件并读出数据,计算总分和平均分
fp=fopen("f:\\stu1.dat","r");
while(1)
{
fscanf(fp,"%ld%s%s%s%s%ld",&x[n].xq,x[n].bj,x[n].xh,
x[n].xm,x[n].xb,&x[n].csny);
s=0;
for(j=0;j<3;j++)
{fscanf(fp,"%f",&x[n].cj[j]);s=s+x[n].cj[j];}
x[n].total=s;x[n].aver=s/3.0;
if(feof(fp)) break;
n++;
}
fclose(fp);
(4)用冒泡法按平均分从高到低排序
for(i=0;i<n-1;i++) //排序
for(j=n-1;j>=i+1;j--)
if(x[j].aver>x[j-1].aver)
{t=x[j];x[j]=x[j-1];x[j-1]=t;}
(5)输出成绩等信息
printf("学期班级学号姓名性别出生年月三门成绩总成绩平均分\n");
for(i=0;i<n;i++)
{
printf("%6ld %8s%12s%8s %s %8ld
",x[i].xq,x[i].bj,x[i].xh,x[i].xm,x[i].xb,x[i].csny);
for(j=0;j<3;j++)
printf("%3.0f ",x[i].cj[j]);
printf("%6.1f %6.1f\n\n",x[i].total,x[i].aver);
}
(6)将成绩等信息写入文件stu2.dat中
fq=fopen("f:\\stu2.dat","w");
for(i=0;i<n;i++)
{ fprintf(fq,"%ld %s %s %s %s %ld
",x[i].xq,x[i].bj,x[i].xh,x[i].xm,x[i].xb,x[i].csny);
for(j=0;j<3;j++)
fprintf(fq,"%f ",x[i].cj[j]);
fprintf(fq,"%f %f\n",x[i].total,x[i].aver);
}
fclose(fq);
}
8、校园卡消费记录
学生信息包括:学号或工号、学院、姓名、消费地点、日期、时间、金额。

主要功能:
(1)能按消费地点完成对消费的录入、修改。

(2能按学号或工号统计消费,求消费者的本月的总消费及日均消费余额,并能根据学生的月消费进行排序。

(3)能查询消费记录清单。

(4)能按工号或学号排序以后输出消费清单。

(1)确定所需的结构类型
struct student
{ char no[20]; //学号或工号
char xy[30]; //学院
char xm[20]; //姓名
char dd[30]; //消费地点
char rq[15]; //日期
char sj[12]; //时间
float je; //金额
};
(2)建立菜单结构(类似学生成绩管理)
main()
{ int op;char ch;
do
{
system("cls");
printf("\n欢迎使用校园卡消费管理系统系统\n");
printf("1. 消费录入 \n");
printf("2. 消费修改 \n");
printf("3. 消费统计 \n");
printf("4. 消费查询 \n");
printf("5. 消费单打印 \n");
printf("6. 退出 \n");
scanf("%d",&op);
switch(op)
{ case 1:a1();ch='Y';break;
case 2:a2();ch='Y';break;
case 3:a3();ch='Y';break;
case 4:a4();ch='Y';break;
case 5:a5();ch='Y';break;
default:ch='N';break;
}
}while(ch=='Y');
}
(3)消费录入
从键盘输入消费记录,保存到磁盘文件中。

void a1()
{ FILE *fp;char yn;
fp=fopen("f:\\rmb.txt","w");
do{
printf("输入学(工)号学院姓名消费地点日期时间金额\n");
scanf("%s%s%s%s%s%s%f",y.no,y.xy,y.xm,y.dd,y.rq,
y.sj,&y.je);
fprintf(fp,"%s %s %s %s %s %s %f\n",y.no,y.xy,y.
xm,y.dd,y.rq,y.sj,y.je);
printf("继续录入吗(y/n)?\n");
scanf("%s",&yn); }while(yn=='y');
fclose(fp);
getch();}
(4)消费修改
先输入要修改人员的学(工)号,然后打开文件,从文
件读出数据,若是要修改人员的信息,进行修改(不
是,则不要修改),然后将信息保存到另一个文件中。

最后从另一个文件将数据保存到原来文件中。

void a2()
{ FILE *fp,*fq;char yn,no[20];
do{ system("cls");
fp=fopen("f:\\rmb.txt","r");
fq=fopen("f:\\rmb1.txt","w");
printf("输入要修改人员的学(工)号 \n");
scanf("%s",no);
while(1){
fscanf(fp,"%s%s%s%s%s%s%f",y.no,y.xy,y.xm,y.dd,y
.rq,y.sj,&y.je);
if(feof(fp))break;
if(strcmp(y.no,no)==0)
{
printf("要修改人员信息如下:\n");
printf("学(工)号学院姓名消费地点日期时间金额\n");
printf("%12s %6s %6s %8s %8s %8s %f\n",y.no,y.xy
,y.xm,y.dd,y.rq,y.sj,y.je);
printf("输入要修改人员的学院姓名消费地点日期时间金额\n");
scanf("%s%s%s%s%s%f",y.xy,y.xm,y.dd,y.rq,y.sj,&y .je);
fprintf(fq,"%s %s %s %s %s %s %f\n",no,y.xy,y.xm ,y.dd,y.rq,y.sj,y.je); }
else
fprintf(fq,"%s %s %s %s %s %s %f\n",y.no,y.xy,y. xm,y.dd,y.rq,y.sj,y.je);
}
fclose(fp);fclose(fq);
fp=fopen("f:\\rmb.txt","w");
fq=fopen("f:\\rmb1.txt","r");
while(1)
{fscanf(fq,"%s%s%s%s%s%s%f",y.no,y.xy,y.xm, y.dd,y.rq,y.sj,&y.je);
if(feof(fq))break;
fprintf(fp,"%s %s %s %s %s %s %f\n",y.no,y.xy,y. xm,y.dd,y.rq,y.sj,y.je);
}
printf("继续修改吗(y/n)?\n");
scanf("%s",&yn);
fclose(fp);fclose(fq);
}while(yn=='y');
getch();
(5)消费统计
先将所有的消费信息从文件读出到数组中(一个人可以
有多次消费记录),将学(工)号相同的记录的消费金
额合并到他的第一项,其它多余的项的消费金额置0,
最后输出每个学(工)号的第一项(当然也可以保存到
文件中)
void a3()
{ FILE *fp;int i,j;
fp=fopen("f:\\rmb.txt","r");
n=0;
while(1){
fscanf(fp,"%s%s%s%s%s%s%f",y.no,y.xy,y.xm,y.dd,y
.rq,y.sj,&y.je);
if(feof(fp))break;
z[n]=y;n++;}
fclose(fp);
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(strcmp(z[i].no,z[j].no)==0)
if(z[i].je==0)break;
else {z[i].je+=z[j].je;z[j].je=0;}
printf("学(工)号学院姓名消费总金额\n");
for(i=0;i<n;i++)
if(z[i].je)
printf("%12s %6s %6s %f\n",z[i].no,z[i].xy,z[i]
.xm,z[i].je);
getch();
}
(6)消费查询
输入要查找人员的学(工)号和姓名,然后打开文件,
从文件读出数据,读出数据与要找的数据相符,则输
出,否则不输出。

void a4()
{ char no[20],xm[20],yn;
FILE *fp;
do{
system("cls");
fp=fopen("f:\\rmb.txt","r");
printf("输入要查询学生的学(工)号和姓名\n");
scanf("%s%s",no,xm);
printf("学(工)号学院姓名消费地点
日期时间金额\n");
while(1){
fscanf(fp,"%s%s%s%s%s%s%f",y.no,y.xy,y.xm,y.dd,y
.rq,y.sj,&y.je);
if(feof(fp))break;
if(strcmp(y.no,no)==0&&strcmp(y.xm,xm)==0)
{
printf("%12s %6s %6s %8s %8s %8s %f\n",y.no,y.xy
,y.xm,y.dd,y.rq,y.sj,y.je);
}}
fclose(fp);
printf("继续查找吗(y/n)?\n");
scanf("%s",&yn);}while(yn=='y');
getch();
}
(7)打印消费单
打开文件,从文件中读出数据到数组中,对数组中的元素按学(工)号排序,使同一个人的消费记录显示在一起,然后打印消费单。

void a5()
{ FILE *fp;int i,j;
fp=fopen("f:\\rmb.txt","r");
while(1){
fscanf(fp,"%s%s%s%s%s%s%f",y.no,y.xy,y.xm,y.dd,y.rq,y.sj,& y.je);
if(feof(fp))break;
x[n]=y;n++;}
fclose(fp);
for(i=0;i<n-1;i++)
for(j=n-1;j>=i+1;j--)
if(strcmp(x[j].no,x[j-1].no)<0)
{ y=x[j];x[j]=x[j-1];x[j-1]=y;}
printf("学(工)号学院姓名消费地点日期时间金额\n");
for(i=0;i<n;i++)
printf("%12s %6s %6s %8s %8s %8s %f\n",x[i].no,x[i].xy,x[i ].xm,x[i].dd,x[i].rq,x[i].sj,x[i].je);
getch();
}。

相关文档
最新文档