1、 本人工作: 主机和客户端的文件操作,主机的数据处理。 系统需求分析: 主程序:模拟产生用户的每月水、电、气三项用量数据,计算出每月费用,总费用费用,并把这些事数据输出到文件,供客户端查询。 客户端:添加、删除用户,查询用户各月各数据,缴费。 程序功能介绍: 主程序(主机.exe):产生随机数的方法模拟用户数据,保存在二维数组中,叠加方法算每月费用,文件操作从文件(flag.txt)中读入用户数量、被删用户账号、写出用户每月各种用量、每月费用在一个文件(file1.txt),总费用在另一文件(total.txt)。 客户端 (link.exe): 打开客
2、户端程序和用户每进行一次操作时都从从初始化文件(name.txt)中读入初始化数据,从文件(file1.txt)中读入用户最近三月各项数据最新数据和文件(total.txt)读入用户累积的总费用的最新数据。 当客户端添加删除用户完毕,把总人数、添加删除用户的账号输出到文件(flag.txt),以供主程序做出处理。 当用户缴费完毕,把最新总分费用数据写入(total.txt)。 当退出客户端时把用户名、对应账号、对应总费用写入初始化文件(name.txt),以便下一次打开客户端时,数据仍在。 数据结构设计: 链表存放用户数据。 结构体数组保存用户数据。 三个二维数组存放用户
3、三个月数据用。 一维数组存放总费用。 一维数组存放删除用户账号。 程序流程图: 退出程序 选择界面 选择 删除用户 增加用户 查询 缴费 输入用户名 成功删除 是否欠费 否 输入姓名 是 是否达到最 大用户数 否 窗口显示 选择 次月份 最近月份 次次月份 缴费情况 输入账号 输出账号 输入交易额 是 初始化数据 源程序(涉及文件操作部分): 主机: char flag=65;//ASCII码中65为A FILE *fp=NULL; FILE *fp1=NULL; FILE *f
4、p2=NULL; fp1=fopen("flag.txt","r+"); if(fp1==NULL) { printf("打开flag.txt错误!"); } rewind(fp1); fscanf(fp1,"%2d",&n);//读入总人数 fclose(fp1); fp=fopen("file1.txt","a"); if(fp==NULL) { printf("打开file1.txt错误!"); } fprintf(fp,"%6.1f",num);//输出标记-1 for (i=0
5、i 6、2000);
fp1=fopen("flag.txt","r+");
if(fp1==NULL)
{
printf("打开flag.txt错误!");
}
rewind(fp1);
fseek(fp1,-4L,SEEK_END);
fscanf(fp1,"%2d",&rank);//读入排行
if(rank!=-1)
{
for(j=rank;j<20;j++)
{
cash[j-1]=cash[j];
}
fseek(fp1,- 7、4L,SEEK_END);
fprintf(fp1,"%2d",-1);//输出标记
}
fp2=fopen("total.txt","w");
if(fp2==NULL)
{
printf("打开total.txt错误!");
}
for(ii=0;ii 8、k(fp1,-2L,SEEK_END);
fscanf(fp1,"%2d",&sign);//读入标记
if(sign==-1)
{
for(j=0;j<20;j++)
{
cash[j]=0;
}
fseek(fp1,-2L,SEEK_END);
fprintf(fp1,"%2d",1);
}
fclose(fp1);
}
客户端:
#include "define.h"
/*函数功能:把name.txt的原始用户名和对应账号读入程序
函数参数: 9、结构体变量inttable,用来保存用户名和对应账号
函数返回值:无
*/
void name(struct init inittable[MAX])
{
FILE *fp=NULL;
fp=fopen("name.txt","r");//以只读方式打开文件
if(fp==NULL)
{
printf("打开用户姓名号码文件出错!");
}
int i;
for(i=0;i 10、e[i].account);//读入账号
fscanf(fp,"%13f",&inittable[i].pay);//读入总费用
}
fclose(fp);
}
/*函数功能:输出删除的用户的账号
函数参数:整形二维数组tableaccount存放删除的用户的账号
函数返回值:无
*/
void del(int tableaccount[MAX])
{
FILE *fp=NULL;
fp=fopen("del.txt","r");//以只读方式打开文件
if(fp==NULL)
{
printf("打开del.txt出错!");
11、 }
int i;
for(i=0;i 12、记
函数返回值:无
*/
void File(int *ptotal,int *prank, float tablepay[20],float table11[20][4],float table22[20][4],float table33[20][4],int monthtable[3],int *sign)
{
char monthflag;//保存月份
FILE *fp=NULL;//定义文件指针
FILE *fp1=NULL;
FILE *fp2=NULL;
fp=fopen("file1.txt","r"); //打开“每月数据”文件
13、if(fp==NULL)
{
printf("打开file1.txt出错!");
}
/*移动文件指针,判断最新月份*/
fseek(fp,-1L,SEEK_END);
fscanf(fp,"%c",&monthflag);
FinalStr(monthflag,table11,table22,table33,fp,monthtable);//把水、电、气数据赋给二维数组
fp1=fopen("flag.txt","w");
if(fp1==NULL)
{
printf("打开flag.txt文件出错!");
}
fprint 14、f(fp1,"%2d",*ptotal);//输出总人数
fprintf(fp1,"%2d",*prank);//输出排行
fprintf(fp1,"%2d",*sign);//输出标记位
fp2=fopen("total.txt","r"); //打开“总费用”文件
if(fp2==NULL)
{
printf("打开total.txt出错!");
}
int i;
for(i=0;i<20;i++)
{
fscanf(fp2,"%13f",&tablepay[i]);//输出总费用
}
fclose(fp); //关闭文件
fcl 15、ose(fp1);
fclose(fp2);
}
/*函数功能:把一个月的数据赋给二维数组
函数参数:浮点型二维数组str,用来保存一个月的数据
指针变量*fp,文件file1的文件指针
函数返回值:无
*/
void CreatStr(float str[USER_NUM][4],FILE *fp)
{
int i;
int j;
float data;
float numflag;
for(i=0;i 16、文件指针比以后多移4个数据位*/
if(i==0)
{
fseek(fp,-30L,SEEK_CUR);
fscanf(fp,"%6f",&numflag);
}
else
{
fseek(fp,-54L,SEEK_CUR);
fscanf(fp,"%6f",&numflag);
}
/*把4个数据依次赋给二维数组中的一维*/
for(j=0;j<4;j++)
{
fscanf(fp,"%6f",&data);
str[i][j]=data;
}
/*如果读到标记-1,则该 17、次赋完后退出*/
if(numflag<0)
{
break;
}
}
int i1,i2,n,m;
float temp[1];
m=i;
n=(m+1)/2;
/*因从文件后面读起,现把二维数组倒置,变回正常顺序*/
for(i1=0,i2=m;i1 18、现在的月份,并把最近三月的数据赋给二维数组
函数参数:字符型变量monthflag,表示最近月的月份
浮点型二维数组str_month1,用来保存最近月数据
浮点型二维数组str_month2,用来保存次月月数据
浮点型二维数组str_month3,用来保存次次月数据
指针变量*fp,文件file1的文件指针
函数返回值:无
*/
void FinalStr(char monthflag,float str_month1[USER_NUM][4],float str_month2[USER_NUM][4],float str_month3[USE 19、R_NUM][4],FILE *fp,int monthtable[3])
{
int n=0;
if(monthflag=='A')
{
monthtable[0]=1;
monthtable[1]=12;
monthtable[2]=11;
}
else if(monthflag=='B')
{
monthtable[0]=2;
monthtable[1]=1;
monthtable[2]=12;
}
else
{
//把读进来的月份数据赋给保存月份的数组
monthtable[0]=monthflag-64;
monthtab 20、le[1]=monthflag-65;
monthtable[2]=monthflag-66;
}
fseek(fp,-1L,SEEK_END);//跳过月份标记位
CreatStr(str_month1,fp);
fseek(fp,-31L,SEEK_CUR);//跳过月份标记位和下月的最后一个用户数据和结束标记位-1
CreatStr(str_month2,fp);
fseek(fp,-31L,SEEK_CUR);
CreatStr(str_month3,fp);
}
void name1 (struct init table[MAX])
把用户名和账号写入name.txt文件,使程序关闭时这些数据不丢失
(与初始化写入时类似,把fscanf改为fprintf,再稍作修改即可。)
总结:
本次课程设计,使自己继续学习了C语言,掌握了结构体,文件操作等课堂未讲却常用的东西,并对以前的知识也有了更深的了解,更熟练地运用。
本次课程设计,也遇到了一些困难,如增加删除用户对文件的读写的影响,通过思考,组员交流,逐一解决了这些问题。
本次课程设计,存在一些的不足,比较大的不足是未能充分利用网络资源,借鉴他人的成果,完全靠自己探索,思考,导致功能不够丰富。






