高级语言课程设计实验指导书.docx
《高级语言课程设计实验指导书.docx》由会员分享,可在线阅读,更多相关《高级语言课程设计实验指导书.docx(26页珍藏版)》请在冰点文库上搜索。
高级语言课程设计实验指导书
高级语言课程设计实验教案模版
本实验是C++程序设计的后续课程,目的是通过本实验课,使得学生更好掌握C++的相关知识,提高学生的编程水平、技能和综合应用C++的能力。
实验工具:
vc++6.0
实验题目为银行活期储蓄管理系统。
系统的功能模块结构图如下:
高级语言课程设计实验教案1
实验项目一、系统主菜单2
实验项目二、开户模块3
实验项目三、存款模块7
实验项目四、取款模块9
实验项目五、计息模块10
实验项目六、查询模块10
实验项目七、排序模块13
C++文件流操作13
实验项目一、系统主菜单
实验内容:
编写系统主菜单
实验目的:
通过实现系统主菜单模块使得学生掌握工程文件中不同文件之间的函数调用方法。
模块实现算法
包含头部文件
函数声明
externvoidkh();开户函数
externvoidck();存款函数
externvoidqh();取款函数
externvoidjx();计息函数
externvoidcx();查询函数
externvoidpx();排序函数
main()
{
while
(1)
{
system(“cls”);//清屏
显示菜单
选择提示并接收用户输入
使用多路选择语句处理用户选择
}
相关知识点:
清屏函数
函数名称
system
头部文件
Stdlib.h
函数用途
调用dos命令
函数原型
Intsystem(constchar*command)
参数
Commanddos命令字符串
容易出现的错误:
①如果将用于接受用户输入选择的变量定义为整型,则当输入非数字字符时候,程序将进入死循环。
②缺少对被调用的函数的引用声明(extern)。
思考:
使用工程的优点
实验项目二、开户模块
实验内容:
编写开户模块
实验目的:
掌握与文件相关的操作
开户模块算法:
函数声明
booluidinput();
函数的功能是输入身份证并验证是否合法(身份证号长度、组成)
合法返回假否则返回真
boolpwdinput();
函数功能是输入密码和确认密码,并验证密码是否合法,如果合法则返回假,否则返回真
boolmoneyinput();
函数功能输入开户金额并验证金额是否合法
合法返回假,否则返回真
voidkh()
{
boolxh;
清屏
身份证输入及验证
do
xh=uidinput();
while(xh);
验证当前身份证是否已经开过户
Personp,p2;//对象p用于接收存放开户信息,对象p2用于存放从帐户文件中读取的帐户记录
以读与添加方式打开帐户文件
C文件操作
C++文件流操作
定义文件指针
FILE*fp
以读和追加写方式打开帐户文件
fp=fopen(char*fileName,”r+a”);
if(fp==NULL)
{
//当前帐户文件为空将当前储户开户信息追加到帐户文件
fwrite(&p,sizeof(zh),1,fp);
关闭文件
fclose(fp);
反馈开户成功信息
返回主菜单
}
else
while(!
feof(fp)
{
读取帐户记录
If(读取帐户的帐号==开户帐号)
{
反馈已经开过户信息
返回系统主菜单
}
}
将开户信息追加到帐户文件
关闭文件
反馈开户成功信息
返回系统主菜单
创建文件流对象
fstreamfile;
以读追加方式打开帐户文件
file.open(char*fileName",ios:
:
in|ios:
:
out|ios:
:
binary|ios:
:
app,0);
while(!
file.eof())
{
读取帐户记录
If(读取帐户的帐号==开户帐号)
{
反馈已经开过户信息
关闭文件流
file.close();
返回系统主菜单
}
}
将开户信息追加到帐户文件
file.write((char*)&ap,sizeof(zh));
反馈开户成功信息
关闭文件流
file.close();
返回系统主菜单
相关知识点:
文件指针定义
FILE*fp;
打开文件(fopen函数)
函数名称
fopen
头部文件
Stdio.h
函数用途
打开一个文件
函数原型
FILE*fopen(char*filename,char*mode)
参数
filename:
文件名称
参数
Mode:
文件打开模式:
a—追加方式打开文本文件
ab—追加方式打开二进制文件
w—只写方式打开文本文件
wb—只写方式打开二进制文件
r—只读方式打开文本文件
rb—只读方式打开二进制文件
r+a—可读可写追加方式打开文本文件
r+—可读可写覆盖方式打开文本文件
返回值
返回文件指针,打开失败返回NULL
文件写操作(fwrite库函数)
函数名称
fwrite
头部文件
Stdio.h
函数用途
往文件的当前位置开始写入size*count个字节的数据
函数原型
intfwrite(void*buf,intsize,intcount,FILE*fp)
参数
fp:
文件指针
参数
Buf:
存放要写入的数据的地址
参数
Size:
写入数据类型的字节数
参数
Count:
写入数据的数量
文件读操作(fread库函数)
函数名称
fread
头部文件
Stdio.h
函数用途
从文件的当前位置开始中读取size*count个字节的数据
函数原型
intfread(void*buf,intsize,intcount,FILE*fp)
参数
fp:
文件指针
参数
Buf:
存放读取数据的指针
参数
Size:
每个数据单位的字节数
参数
Count:
读取的数据单位个数
关闭文件
fclose(FILE*);
函数名称
fclose
头部文件
Stdio.h
函数用途
关闭文件
函数原型
ntfclose(FILE*fp)
参数
fp:
文件指针
判断是否到达文件结尾函数(feof库函数)
函数名称
feof
头部文件
Stdio.h
函数用途
检测文件位置指示器是否已到结尾
函数原型
intfeof(FILE*stream)
参数
fp:
文件指针
返回值
0-未到文件结尾,1-已到文件结尾
字符串比较函数:
函数名称
strcmp
头部文件
string.h
函数用途
字符串比较
函数原型
intstrcmp(char*str1,char*str2)
参数
str1,str2待比较的字符串
返回值
小于0:
str1str1=str2,大于0:
str1>str2
字符串长度函数
函数名称
strlen
头部文件
string.h
函数用途
得到字符串长度
函数原型
intstrlen(constchar*s)
参数
s待求长度的字符串指针
返回值
字符串的长度
判定字符是否数字字符函数
函数名称
isdigit
头部文件
ctype.h
函数用途
测试参数是否为数字0-9
函数原型
intisdigit(intch)
参数
ch被测参数
返回值
非零-是,0-不是
判断字符是否是数字或字母字符isalnum
函数名称
isalnum
头部文件
ctype.h
函数用途
测试参数是否为大、小写字母或数字
函数原型
intisalnum(intch)
参数
ch被测参数
返回值
非零-是,0-不是
字符串复制库函数strcpy
函数名称
strcpy
头部文件
string.h
函数用途
将字符串src拷贝到字符串dest中去
函数原型
char*strcpy(char*dest,constchar*src)
参数
dest目的字符串,src源字符串
返回值
指向dest的指针
从控制台读取字符库函数getch
函数名称
getch
头部文件
conio.h
函数用途
从控制台读取一个字符,但不显示在屏幕上
函数原型
intgetch(void)
返回值
读取的字符
消息框函数
MessageBox(0,"提示","提示",0);
容易出现的错误.
打开文件的方式与要进行的操作不符
文件绝对路径中的转义字符\\
用于存放密码的数组开辟的单元不够
在逐个输入密码后缺少字符串结束字符\0
在判断当前用户是否开过户时,未遍历所有记录而做出结论
忘记关闭文件
获取系统日期举例:
⑧系统时间的获取示例:
#include
#include
voidmain()
{
time_tt;
t=time(NULL);
tm*T=gmtime(&t);
intyear=T->tm_year+1900;
intmonth=T->tm_mon+1;
intday=T->tm_mday;
inthour=T->tm_hour+8;
intmin=T->tm_min;
intsec=T->tm_sec;
cout<"<"<}
实验项目三、存款模块
实验内容:
存款模块的设计与实现
实验目的:
掌握文件记录的定位与修改
存款模块算法
包含头部文件
定义帐户对象或引用(问题:
如何在不同的文件中共享帐户类)
Voidck()//存款函数
{
//清屏
//提示并输入身份证号码(帐户号码)和存款金额
//输入提示
cin>>p.uid;
//金额验证
//以读写方式打开帐户文件
FILE*fp=fopen(“文件名称”,”r+w”);
do(!
feof(fp))//未到文件结尾
fread(&p2,sizeof(person),1,fp);//读取文件指针所指的帐户记录将其存放于对象p2中
//验证是否与存款帐户号码(身份证号码)是否相等
If(!
strcmp(p.uid,p2.uid))
{
将文件指针定位于当前存款客户的帐户记录
将当前客户的修改了存款余额的帐户记录(对象)写回帐户文件(覆盖)
关闭文件
反馈存款成功信息
返回主菜单
}
}
//帐户文件遍历结束
关闭文件
//反馈帐号不存在信息
//返回主菜单
相关知识
文件指针定位函数:
函数名称
fseek
头部文件
stdio.h
函数用途
设定文件操作指示器位置
函数原型
intfseek(FILE*fp,LONGoffset,intorigin)
参数
fp文件指针
offset相对于origin规定的偏移位置量
origin指针移动的起始位置,可设置为以下三种情况:
SEEK_SET0文件开头
SEEK_CUR1当前读写的位置
SEEK_END2文件尾部
容易出现的错误:
文件指针定位不正确
思考:
系统功能之间的序的问题?
实验项目四、取款模块
实验内容:
取款模块的设计与编码实现
实验目的:
进一步掌握文件操作和编程训练。
取款模块算法
包含头部文件
定义帐户对象
Voidqk()//取款函数
{
清屏
输入身份证号码和密码
以读写方式打开帐户文件
File*fp=fopen(“文件名称”,”r+w”);
while(!
feof(fp))//当帐户文件未遍历结束
{
读取文件指针当前所指的帐户记录并存放于对象p2
If(p2.身份证号码与用户输入的身份证号码相同且密码也相同)
{
输入取款金额并校验
.验证是否可能透支
If(可能透支)
{
反馈帐户存款不足信息
关闭文件
返回主菜单
}
else
{
修改当前客户的存款余额
将文件指针定位于当前客户的帐户记录
将修改存款余额后的对象写入帐户文件(覆盖)
反馈取款成功信息
关闭文件
返回系统主菜单
}
}
遍历结束
关闭文件
反馈非法用户信息
返回主菜单
容易出现的错误
在查询用户时未将身份证号码和密码同时验证。
思考:
存款模块、款模块有何共性?
实验项目五、计息模块
实验内容:
实现对所有帐户批处理计息。
实验目的:
正确掌握文件指针的定位
计息模块算法:
计算当前帐户文件中的帐户个数n
对帐户文件中所有帐户计息
For(inti=1;i<=n;i++)
{
将指针定位于帐户文件中第i个记录
读取第i个记录
计算第i个帐户记录的利息
将指针定位于帐户文件中第i个记录
修改第i个帐户记录覆盖帐户文件中原有的第i个帐户记录。
}
反馈计息结束信息。
容易出现的错误:
在批处理时候,在读取记录时没有定位。
思考:
当完成一个写操作时候,文件指针是否移动到下一个记录?
实验项目六、查询模块
实验内容:
实现查询用户的当前存款余额并以人民币大写的形式输出
实验目的:
掌握映射算法
容易出现的错误:
算法不好
人民币大写示例:
#include
#include
#include
intnum[8];//用于存储组成金额的数值
intlength;//用于存放组成金额的数值个数
booljy(inti)//用于验证从第i个数值后是否还存在非零数值
{
intj;
for(j=i;j<=length;j++)
if(num[j])returntrue;//存在非0数值
returnfalse;//不存在非0数值
}
voidmain()
{
MessageBox(0,"人民币大写示例","提示",0);
cout<<"请输入人民币数目:
";
intmoney;
cin>>money;
if(money>99000000)
{
MessageBox(0,"金额过大","提示",0);
return;
}
//处理0元
if(money==0)
cout<<"零元";
else//非0元
{
//定义大写映射数组
chardx[10][3]={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
//定义单位映射数组
chardw[8][5]={"元","十","百","千","万","十万","百万"};
//将钱以逆序存放于数组
inti=0;
intfl=0;//用于统计非0数值的个数处理整百、千、万...的特殊数值
while(money)//将组成金额的数值分离出来
{
num[i]=money%10;//求当前金额的个位数值
cout<if(num[i])
fl++;//累计非0数出现次数
money/=10;//去掉当前金额的个位
i++;
}
--i;
//将金额分离完毕
length=i;
if(fl<2)//10的整数倍
{
printf(dx[num[i]]);
printf(dw[i]);
printf("元");
}
else
{
intindex;
boolfirst=true;//第一次遇到0标识
while(i>=0)
{
index=num[i];
if(index)//非零数字
{
printf(dx[index]);//输出大写
printf(dw[i]);//输出人民币单位
first=true;//第一次遇到0标识
}
else
{
if(first&&jy(i))//如果是第一次遇到0且此位以后还存在非0数值
printf("零");
first=false;//将第一次遇到0的标识设置为假
}
i--;
}
}
}
思考:
在验证用户身份时,为何用户标识和密码同时验证?
实验项目七、排序模块
实验内容将现有储户按照余额以为降序排序。
实验目的:
动态数据结构及排序训练。
知识点:
动态分配内存空间函数:
allocmem
函数名称
allocmem
头部文件
dos.h
函数用途
按节(16字节)分配内存块
函数原型
intallocmem(unsignedsize,unsigned*seg)
输入参数
size分配的节数
输出参数
seg分配后的段地址
返回值
-1分配成功,其他数值-实际分配的节数
动态分配内存空间函数:
freemem
函数名称
freemem
头部文件
dos.h
函数用途
释放由allocmem()分配的内存块
函数原型
intfreemem(unsignedseg)
输入参数
seg段地址
返回值
0-操作成功,-1操作失败
思考:
动态申请的存储单元的生存期为?
C++文件流操作
在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础。
stream这个类有两个重要的运算符:
1、插入器(<<)
向流输出数据。
比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"WriteStdout"<<'n';就表示把字符串"WriteStdout"和换行字符('n')输出到标准输出流。
2、析取器(>>)
从流中输入数据。
比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)
的数据。
在C++中,对文件的操作是通过stream的子类fstream(filestream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。
一、打开文件
在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:
voidopen(constchar*filename,intmode,intaccess);
参数:
filename:
要打开的文件名
mode:
要打开文件的方式
打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
ios:
:
app:
以追加的方式打开文件
ios:
:
ate:
文件打开后定位到文件尾
ios:
app就包含有此属性
ios:
:
binary:
以二进制方式打开文件,缺省的方式是文本方式。
ios:
:
in:
文件以输入方式打开
ios:
:
out:
文件以输出方式打开
ios:
:
nocreate:
不建立文件,所以文件不存在时打开失败
ios:
:
noreplace:
不覆盖文件,所以打开文件时如果文件存在失败
ios:
:
trunc:
如果文件存在,把文件长度设为0
可以用“或”把以上属性连接起来,如ios:
:
out|ios:
:
binary
access:
打开文件的属性
打开文件的属性取值是:
0:
普通文件,打开访问
1:
只读文件
2:
隐含文件
4:
系统文件
可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。
例如:
以二进制输入方式打开文件c:
config.sys
fstreamfile1;
file1.open("c:
config.sys",ios:
:
binary|ios:
:
in,0);
特别提出的是,fstream有两个子类:
ifstream(inputfilestream)和ofstream(outpufilestream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。
ifstreamfile2("c:
pdos.def");//以输入方式打开文件
ofstreamfile3("c:
x.123");//以输出方式打开文件
所以,在实际应用中,根据需要的不同,选择不同的类来定义:
如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
二、关闭文件
打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:
file1.close();就把file1相连的文件关闭。
三、读写文件
读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式
文本文件的读写
文本文件的读写很简单:
用插入器(<<)向文件输出;用析取器(>>)从文件输入。
假设file1是以输入方式打开,file2以输出打开。
示例如下:
file2<<"ILoveYou";//向文件写入字符串"ILoveYou"
inti;
file1>>i;//从文件输入一个整数值。
这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些
操纵符功能输入/输出
dec格式化为十进制数值数据输入和输出
endl输出一个换行符并刷新此流输出
ends输出一个空字符输出
hex格式化为十六进制数值数据输入和输出
oct格式化为八进制数值数据输入和输出
setpxecision(intp)设置浮点数的精度位数输出
比如要把123当作十六进制输出:
file1<file1<2、二进制文件的读写
①put()
put()函数向流写入一个字符,其原型是ofstream&put(charch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。
②get()
get()函数比较灵活,有3种常用的重载形式:
一种就是和put()对应的形式:
ifstream&get(char&ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。
如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。
另一种重载形式的原型是: