银行储蓄系统:结构体版本、二进制版本

下面讨论二进制版较结构体版的不同,优势,两难,改进之处:

不同:

(一)全局变量

结构体版:

struct record users[upNum];   //银行所有用户
int N;                                        //实际的用户数目
二进制版:

int N;
FILE *fp;

全局变量的结构体数组->子函数中定义指向结构体的指针

fp由局部变量->全局变量


(二)main函数

结构体版:

int main()
{printf("+----------------------+\n");printf("+    欢迎光临CSDN银行  +\n");printf("+----------------------+\n");if (pass()){readData();work();writeData();}return 0;
}

二进制版:

int main(){FILE *fp;printf("+----------------------+\n");printf("+    欢迎光临我家银行  +\n");printf("+----------------------+\n");if (pass()){exchange();    //将数据从文本文件读到二进制文件if((fp=fopen("account.bin", "rb+"))==NULL)   //文件不存在时重建,文件已经存在时,将保留原数据{printf("数据文件打开失败,退出程序....");exit(1);}fseek(fp, 0, SEEK_END);N = ftell(fp)/sizeof(record);  //ftell用于得到文件位置指针当前位置相对于文件首的偏移字节数,除以sizeof(struct record),得到的是当前用户的数目work();fclose(fp);}return 0;}

结构体版readData(),writeData() 需要用到大数组操作,需要读写所有的数据信息;

二进制版运用随机读写,只要定位到某账户所在的文件指针位置,不再需要内存中的大数组。


(三)二进制的业务员文件及存储

结构体版:

int pass()
{...if ((fp=fopen("worker.txt", "r"))==NULL){printf("password file cannot open!");exit(0);}fscanf(fp, "%s %s", sNameInFile, sPassInFile);  //从文件中读业务员用户名和密码密码fclose(fp);//进入系统,密码三次不对将退出do{...}while(iTry);return right;
}

二进制版:

int pass()
{...if ((fp=fopen("password.dat", "rb"))==NULL){printf("第一次使用,将设置初始操作员账户:\n");printf("请输入用户名:");scanf("%s",sName);printf("请输入密码:");iPass1=inputPassword();  //输入密码1printf("确认密码:");iPass2=inputPassword();  //输入密码2if(iPass1==iPass2){fp=fopen("password.dat", "wb");fwrite(sName, sizeof(sName), 1, fp);fwrite((char*)&iPass1, sizeof(int), 1, fp);right = 1;fclose(fp);}else{printf("两次密码不一致,设置不成功!\n");exit(0);}}else{fread(sNameInFile, sizeof(sNameInFile), 1, fp);  //从文件中读业务员用户名fread((char*)&iPassInFile, sizeof(int), 1, fp);  //密码fclose(fp);//进入系统,密码三次不对将退出do{...}while(iTry);}return right;
}

结构体版中用字符数组保存业务员密码;二进制版中密码采用整型,添加了打开失败的处理

(四)从文件中读取以及更新内容——以取款为例

结构体版:

void withdraw()
{...printf("账号:");scanf("%d", &id);who = search(id);  //根据账号查询用户,返回用户的下标if(who<0)   //说明id账户不存在{printf("该用户不存在,取款失败!\n");}else{if(users[who].status==0){printf("户主姓名:%s\n", users[who].name);printf("密码:");iPass=inputPassword();if(iPass!=users[who].password){printf("输入密码错误,取款失败!\n");}else{printf("输入取款额:");scanf("%lf", &money);if(money>users[who].balance)  //亲,不玩透支{printf("余额不足,取款失败!\n");}else{users[who].balance-=money;printf("取款后,还有%.2f元. \n",users[who].balance);}}}else if(users[who].status==1)...else...}return;
}
int search(int id)
{int index=-1;int i;for(i=0; i<N; i++){if(users[i].account==id){index=i;break;   //找到了,立即退出循环}}return index; //若找到,其值在0~N-1间,否则,保持-1
}

二进制版:

void withdraw()
{...record *user;user = getuser();  //输入并查询用户,不存在返回NULLif(user!=NULL){if(user->status==0){printf("户主姓名:%s\n", user->name);printf("密码:");iPass=inputPassword();if(iPass!=user->password){printf("输入密码错误,取款失败!\n");}else{printf("输入取款额:");scanf("%lf", &money);if(money>user->balance)  //亲,不玩透支{printf("余额不足,取款失败!\n");}else{user->balance-=money;writeData(user);printf("取款后,还有%.2f元. \n",user->balance);}}}else if(user->status==1)...else...free(user);}return;
}
record* getuser()
{FILE *fp;if((fp=fopen("account.bin", "rb+"))==NULL)   //文件不存在时重建,文件已经存在时,将保留原数据{printf("数据文件打开失败,退出程序....");exit(1);}int id;printf("账号:");scanf("%d", &id);record *user = NULL;if(id>=N+10001)//说明账户不存在{printf("该用户不存在,查询完毕!\n");}else{fseek(fp,(id-10001)*sizeof(record), SEEK_SET);user=(record*)malloc(sizeof(record));fread((char*)user, sizeof(record), 1, fp);}fclose(fp);return user; //若找不到,user为NULL
}
void writeData(record *user)
{FILE *fp;if((fp=fopen("account.bin", "rb+"))==NULL)   //文件不存在时重建,文件已经存在时,将保留原数据{printf("数据文件打开失败,退出程序....");exit(1);}//先在文件中定位long i = user->account -10001;fseek(fp, (long)i*sizeof(record), SEEK_SET);fwrite((char*)user, sizeof(record),1,fp);fclose(fp);
}

二进制版随机读取并采用动态分配内存的方式,避免大数组操作和节省空间

(五)创建二进制文件account.bin用来保存储户信息

#define upNum 2000           //估计一个超出原实际储户的大数
void exchange(){FILE *fp;record users[upNum];     //存放数据的一段内存空间int i=0,N;/*事先将储户信息输入到文本文件中*/if((fp=fopen("account.dat","r"))==NULL){   printf("account.dat cannot be opened");exit(1);}/*将文本文件中的信息读到内存*/while(fscanf(fp,"%d %s %d %lf %d",&users[i].account, users[i].name, &users[i].password, &users[i].balance,&users[i].status ) != EOF)i++;N=i;fclose(fp);if((fp=fopen("account.bin","wb"))==NULL){printf("account.bin cannot be opened");exit(1);}/*将内存数据读到二进制文件中*/fwrite((char*)&users[0],sizeof(users[0]),N,fp);fclose(fp);
}


优势:

二进制文件:空间省、效率高、保密。结合随机读取,自由灵活,适用大文件

两难:

fp作为全局变量,又是指针,在整个文件中起作用,生存周期长

若将fp作为局部变量(定义FILE *fp;fopen();fclose();),但会在writeData(),getuser()中频繁调用,使用外存,过程缓慢

改进之处:索引+随机访问

实际应用中数据文件未必顺序存储,但账号不会重复,
使用数据在内存中的偏移量代替序号,声明第几条记录
把偏移量和账号抽取出来作为排序前索引,根据账号查出是第几条记录
通过以账号进行排序后的索引文件,将索引数据读到内存,快速查找到账户信息
查找账号->偏移量->储户数据信息

C语言进阶-第39讲:银行储蓄系统(二进制版)开发相关推荐

  1. 银行账户管理系统c语言链表,课程设计银行储蓄管理系统Word版

    <课程设计银行储蓄管理系统Word版>由会员分享,可在线阅读,更多相关<课程设计银行储蓄管理系统Word版(22页珍藏版)>请在人人文库网上搜索. 1.传播优秀Word版文档 ...

  2. 银行办理CSS系统,简单的银行储蓄系统.doc

    PAGE PAGE 2 哈 尔 滨 理 工 大 学 毕 业 设 计 题 目: 简单的银行储蓄系统 院 .系: - 学院 - 工程系 姓 名: - - 指导教师: - - 系 主 任: - - 2012 ...

  3. 软件工程导论 银行储蓄系统_银行计算机储蓄系统

    银行计算机储蓄系统 题目:银行帐户管理,储蓄业务管理处理系统 班级:计算机科学与技术( 3 )班 设计者:易华丽 1 引言 1.1 编写目的 本报告的目的是规范化本软件的编写,旨在于提高软件开发过程中 ...

  4. Day11-软件测试设计之银行储蓄系统

    银行储蓄系统 需求分析 银行储蓄系统存取款流程如下: 1. 业务员事先录入利率信息.  2. 如果是存款,储户填写存款单,业务员将存款单键 入系统,系统更新储户存款信息(存款人姓名.存款人账号.电话号 ...

  5. 学术休假之银行储蓄系统

    银行储蓄系统指导 该银行储蓄系统的目标,将是设计一个可以支持多名储户开户.存款.取款.转帐.改密.挂失.解挂.销户等功能的系统,以此初步体会完整系统开发,综合运用已经学过的知识. 以下提示中,给出了多 ...

  6. 银行储蓄系统的可行性分析

    作业题目 题目: 为方便储户,某银行拟开发计算机储蓄系统.储户填写的存款单或取款单由业务员输入系统,如果是存款,系统记录存款人姓名.住址.存款类型.存款日期.利率等信息,并印出存款单给储户:如果是取款 ...

  7. 数据结构课程设计银行储蓄系统

    /** *版权所有(C)2017,panyanan * *文件名称:main.cpp *文件标识:无 *内容摘要:本文件的作用是调用算法库里面的函数,完成题目要求. *其它说明:无 *当前版本:V1. ...

  8. 软件工程导论 银行储蓄系统_银行储蓄系统问题定义及其可行性

    1.问题定义(系统目标及范围说明书): 项目名称:XX银行储蓄业务系统 问题描述:方便储蓄用户存取等业务.解决当前银行业务员处理储蓄业务时间消耗长.工作量大.效率低 项目目标:开发一个方便储蓄用户的银 ...

  9. C语言之简单版本银行储蓄系统4(结构体版本)

    1.老学长的唠叨 在上一个编的数组版本的简化银行系统的基础上改为结构体存储,为还没有学到结构体的学弟学妹们提供一个迁就的方案,现在将程序改为结构体存储了,也希望学弟学妹们有个c语言学习缓冲的时间,这个 ...

最新文章

  1. 【转】centos 6.2 安装mysql-5.5.17
  2. raspberry pi 3B 树莓派 安装tensorflow
  3. html select 可输入 可编辑
  4. mongodb模糊查询_AWS 回击了!推出兼容 MongoDB 的 DocumentDB
  5. arduino判断是否连接串口_Arduino-串口通信
  6. ae渲染出现错误是什么问题_[Switch]解决OPENWRT路由,使用UU加速器等出现相同IP,DNS解析错误问题...
  7. mysql部署策略_MySQL延迟问题和数据刷盘策略流程分析
  8. 利用hutool工具类导出Excel
  9. Visual Studio 2010 (ASP.Net 4.0)新功能一览(转载)
  10. VirtualDub - 开源视频捕捉及线性处理软件
  11. 面试题之——多线程详解
  12. vbs实现恶搞无限弹窗,复制粘贴就能用
  13. 看看“电子招投标平台”是如何识破“围标串标”的,看完少走弯路
  14. socket编程详解(一)——服务器端
  15. Oracle Data Pump Schema 方式导入导出
  16. win10怎么更新显卡驱动_Intel发布核显新驱动:支持Win10 H2更新、11代酷睿狂喜-Intel,核显,驱动,Win10 ——快科技(驱动之家旗下媒体)-...
  17. nginx动静分离和资源隔离的网站搭建
  18. 敏捷项目管理21天学习计划--敏捷生命周期
  19. 「兔了个兔」玉兔踏青,纯CSS实现瑞兔日历(附源码)
  20. ffmpeg加水印、logo等

热门文章

  1. 基于Spark的电影推荐系统(推荐系统~5)
  2. 配置PPPOE拨号和固定IP上网-从零开始学RouterOS系列02
  3. Java 中模板下载
  4. AutoCAD2021 下载及安装教程
  5. FFMPEG API函数根据SDP文件接收RTP媒体流
  6. html纵向字幕无缝滚动,html文字无缝滚动代码
  7. 为什么要用收费邮箱,免费邮箱和付费邮箱的差别
  8. Java中内嵌浏览器
  9. julia语言科学计算_Julia –数值计算和数据科学的新方法
  10. 上奇产业通:全国人工智能产业分析报告