1、个人财政支出管理付欣 05计算机四班指导老师:梁新元一、问题描述及分析1二、实验程序设计思想及功能描述13、主要函数模块的设计思想和具体实现2三、实验程序测试41、程序开始执行时系统的所显示的页面:42、选择退出系统:53、选择登陆,并且输入的帐号和密码都正确:54、用户输入的帐号不正确:55、用户输入的帐号正确,密码不正确:6四、实验程序自我评价7五、课程设计创新7六、课程设计总结7七、参考书目:7八、实验程序源代码8一、问题描述及分析编写一个个人财政支出管理系统,主要解决的问题是作为一个系统而言,它所要面对不只是某一个人而言,而是要面对很多的用户。那么想要解决这一问题,就必须要求这个系统能
2、够存储许多用户的基本信息和记录。同时也要求系统能够对不同的用户的身份进行查找和验证。在验证通过之后,在对其进行用户所要求的操作。作为一个财政支出系统,那么就要求对于用户关于金钱的每一项操作都要有相应的记录,同时并允许用户对于每一条整体的记录进行操作,例如可以根据时间来查找某一确定日期是否进行了收入或者支出的操作,也可以根据特定的需要来删除某一条整体的记录。但不允许对每条记录的单项数据进行更改,因为不管是收入还是支出,所涉及的金额都是固定的,时间也是固定的,所以系统不允许用户对其进行操作。除此之外,还必须有足够大的空间来存储新的记录。所以此程序就是基于这个思想而编写出来的,基本满足了用户对于一个
3、财政支出管理系统所要求的相关功能。二、实验程序设计思想及功能描述根据前面对于编写一个个人财政支出管理系统的程序的问题描述和分析,确定了此程序的基本思想和相关功能。1、 基本思想首先定义一个结构体数组,这个数组的功能便是用来所有用户的所有信息。它的成员为每个用户的帐号(account)、密码(code)、姓名(name)、记录(record recmax),以及记录的条数(rec_len)。其中记录(record recmax)这个成员本身也是一个结构体数组。它包含了用户所有的记录(record),并且根据用户的操作,记录这个成员变量也会有所跟改,例如如果拥护增加了一条记录,那么这一条记录就会存
4、储在此成员变量中。除了这个成员变量是动态变化之外,记录的条数(rec_len)也会根据用户的操作进行变化,例如如果用户增加了一条记录,则rec_len就会自加1,如果用户删除了一条记录,则rec_len就会自减1。记录(record recmax)这个成员变量是以后函数中操作的主要内容。除了这两个成员变量之外,其它的成员变量则不会被改变,系统只允许用户对其进行访问,但不允许进行操作,因为这几个成员变量的作用主要是用来验证用户的身份用的,所以不可以更改。其中的密码(code)甚至只能别系统调用,而不能对用户进行显示的,也就是说密码(code)对于用户是不可预知的,这样做的目的是为了系统自身的安全
5、性,以免用户的信息被其他人看到。这就是这个结构体数组的功能和基本成员变量及各个成员变量的功能。定义了结构体数组之后,首先要做的就是要把所有的记录都存入这个结构体数组中,以方便用户的操作。所以在main函数中有系统自行调用了old_record这个函数来存入信息。在此之后进行的操作便是让用户选择所要进行的是登陆系统的操作还是退出系统的操作。如果选择登陆,则要输入帐号和密码。之后由系统来检查帐号的存在性和密码的正确性。如果这两项都通过了系统的检查,那么用户便可以进行具体记录的操作了。这便是这个程序的基本设计思想。2、各个函数模块的功能(1)old_record( ):此函数由系统自行调用,作用是将
6、所有用户信息存入系统。(2)void save( ): 此函数的作用是将结构体数组中的信息写入文件存储,由系统调用。(3)load( ):此函数的作用是将结构体数组中写入文件的信息读出,由系统调用。(4)lookup_accounts( ):此函数的作用是将用户输入的帐号与系统中的所有帐号进行对比,查看系统中是否有此帐号。(5) check_code( ):此函数是作用是在系统查询到了帐号之后,对用户输入的帐号和密码进行检验,看是否相对应。(6)print_message( ):此函数的功能是在系统检查了用户输入的帐号和密码之后,如果用户通过了系统的检查,在此显示用户可见的基本信息。(7)fi
7、nd_record( ):此函数的作用是根据用户输入的日期进行查找操作。(8)insert_record( ):此函数的功能是在记录中增加一条新的记录,这个记录由用户输入。(9)del_record( ):此函数的功能是根据用户的输入的位置,将相应位置的记录删除。(10)sum_num( ):此函数的功能是计算所有收入和支出的总和,计算全部的收入的总合,计算全部输出的总合。(11)打印输出记录的函数:在本程序中一共有三个打印输出记录的函数,分别为all_print( )、acc_print( )、pay_print( )这三个函数。它们的功能依次是打印输出全部记录,打印输出输入记录,打印输出支
8、出记录。(12)mian( ):在主函数中,可以根据用户的选择来操作系统允许用户使用的功能,也可以随时退出这个系统。3、主要函数模块的设计思想和具体实现(1)void save( )函数 和load( )函数。这两个函数的功能是在系统调用了old_record( )这个函数之后,结构体内就有了所有用户的所有信息。Save( )函数的作用是将所有的信息都存入文件中,便于数据的保存和读取。Load( )函数的作用则是把存入的文件中的信息读出来。这两个函数所涉及的知识点为文件的读入和写出。主要是freadhe和fwrite两个函数的应用。它们的一般调用形式为:fread(buffer,size,co
9、unt,fp);fwrite(buffer,size ,count,fp);其中:Buffer:是一个指针,对fread来说,它是读入数据的存放地址。对fwrite来说,是要输出数据的地址。Size:要读写的字节数。Count:要进行读写多少个size字节的数据项。Fp;文件型指针。调用这两个函数之后,如果调用成功,则函数返回值为count的值,即输入或输出数据项的完整个数。(2)lookup_accounts( )函数和 check_code( )函数:这两个函数的功能主要是用来核对用户的身份。系统先检验的是axxounts这个函数。根据用户输入的帐号与系统中所有的帐号进行比较,查找看是否有
10、相同的。如果找到了,则进行对密码进行检验,看密码与帐号是否对应。在检验帐号的时候,如果用户输入的帐号在系统中不存在,系统则会给出提示要求用户从新输入。但如果用户输入了三次体统都找不到帐号的时候,系统则会强制要求用户退出系统,此时则显示结束语的欢迎词。而如果帐号找到了,但用户输入的密码与原有密码不一致,系统也会给出提示信息要求用户再次输入。同样的,如果用户输入三次体统都检验到不是正确的密码的时候,系统则会强制要求用户退出系统,此时则显示结束语的欢迎词。在这两个函数中主要用到的知识点就是对字符串的相关操作。如果帐号和密码都通过检验之后,此函数则将返回struct list_record类型的数据。
11、字符串处理的函数主要有以下几个:puts函数:其一般形式为puts(字符数组)。其作用是将一个字符串输出到终端。Gets函数:其一般形式为gets (字符数组)。其作用是从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址。Stract函数:其一般形式为strcat(字符数组1,字符数组2)。Strcat是字符串连接的缩写。其作用是连接两个字符数组中的字符串,把字符串2接到字符串1的后面,结果放在字符数组1 中,函数调用后得到一个函数值字符数组1的地址。Strcpy函数:其一般形式为strcpy(字符数组1,字符数组2)。Strcpy是字符串复制的简写。它的作用是将
12、字符串2复制到字符数组1中去。在本程序中。用到的最多的便是此函数。strcmp 函数:其一般形式为strcmp(字符串1,字符串2)。Strcmp是字符串比较的缩写。它的作用是比较字符串1和字符串2,比较的结果有函数值带回。如果字符串1=字符串2,则函数值为0;如果字符串1大于字符串2,则函数值为一个正整数,否则则为负整数。(3)find_record( )函数:此函数的功能是根据用户输入的时间查找当天的记录。这个函数的参数为一个指向结构体的指针和一个字符串。字符串是用语输入的日期,指向结构体的指针指向的则是用户输入的帐号的这个结构体。如果找到了用户输入的日期,则输出当天的所以记录。如果找不到
13、,则显示无此日的记录。(4)insert_record( )函数和del_record( )函数:这两个函数的功能是增加新的记录和删除用户指定的记录。在insert_record( )函数中,此函数的参数是一个指向struct list_record的指针和一个指向struct record的指针还有一个选择插入位置的整形变量。在主函数中,先定义一个struct record的结构体。这个结构体的内容是由用户输入的,也就是用户所要向struct list_record这个结构体中输入的新的记录的内容。然后再在主函数中定义一个指向struct record结构体的指针,并指向已经输入记录的结构体
14、,最后将此指针作为实参传入函数。由于向函数中传如是指针,所以在函数中记录更改之后,返回主函数的是更改后的记录。在del_record( )函数中,有用户在主函数中输入要删除的记录的位置,然后调用此函数,那么就会执行删除该记录的操作。与insert_record函数一样,参数传递的也是指针,所以在函数中更改的记录,返回主函数后依旧是更改后的记录。(5)sum_num( )函数:此函数的功能是用来计算用户所有记录中的钱数的总和,以方便用户对于系统的操作,同时也可以使用户对自己的帐户有更深入的了解。除此之外,该函数还能会对用户所有的收入和所有的支出进行求和,使用户能够知道自己的所有的收入的总和和所有
15、支出的总和,这样也方便了用户进行下一步的操作。(6)打印输出函数: 在此程序中,打印输出函数共有三个,分别是输出全部记录,输出收入记录和输出支出记录。在这里定义三个输出函数是为了方便用户能够更容易的进行操作。假设只有一个输出全部记录的函数,那么如果用户只想查看收入的记录或者支出的记录,此时用户只能自己一条一条的去查看,这样就会让用户感到不方便。一个良好的管理系统的目的就是能尽可能的满足用户的所有需要,分工越是精确越好,所以为了满足此项要求,在此定义了三个输出函数。(7)main( )函数:在一个程序中,main( )函数是最为重要的一个函数,因为它是所有程序执行的入口。同时函数也是以main(
16、 )函数的结束作为结束的,由此可见main( )函数的重要性。在本程序中,所以的功能模块函数都是在main( )函数中调用的,这样做的目的是为了是整个程序的结构简单紧凑,同时也是为了程序的调试方便。但这样也就相对的增加了main( )函数的复杂性。在本程序中,main( )函数中涉及的语法知识包括循环的嵌套使用,分之结构的嵌套使用,指针的应用,指向结构体指针的应用等许多语法结构。因为main( )函数在本程序中有着至关重要的作用,所以在此详细说明。在程序开始执行之后,首先由用户来选择是要登陆系统还是要推出系统。如果是退出系统,那么程序便会结束。如果选择登陆,那么系统便会要求用户输入帐号和密码。
17、系统先会对帐号进行检查,如果检查通过了,则要对密码进行检查,如果通过了,则会显示用户信息,同时也允许用户对记录进行操作,而所有的操作都是由用户自行随意选择的,直到用户选择退出系统之后,程序便会结束。这是在用户输入的帐号和密码都通过检查的情况。如果帐号没有通过检查,系统便会要求用户重新输入,然后系统再对其进行检查,通过了就继续,通不过则还要重新输入,但用户输入帐号的次数最多只有三次。三次之后,系统变会自行推出。如果帐号通过了检查,而密码没有通过,那么系统也会要求用户重新输入,同样输入的次数不会超过三次,否则系统便会自行退出。这便是main( )函数的具体设计思想和具体的功能的描述。三、实验程序测
18、试1、程序开始执行时系统的所显示的页面:2、选择退出系统:3、选择登陆,并且输入的帐号和密码都正确:4、用户输入的帐号不正确:5、用户输入的帐号正确,密码不正确:6、用户进行具体操作:四、实验程序自我评价在这个程序中,我认为我已经完成了所要求的基本操作,同时也增加了相应的功能模块来让用户操作。设计的基本原则就是尽可能的满足用户的所有要求,同时也能尽可能方便的使用户对系统进行操作。虽然这个程序可能还有不足之处,但我对于这个程序还是比较满意的。五、课程设计创新本程序主要模仿是是银行的ATM机的相关功能,除此之外,还增加了允许用户对于记录的一些操作。而不是只允许用户进行查看,这样就增加了系统的灵活性
19、。六、课程设计总结本程序在编写是,主要就是基于用户的角度去分析该如何设计此程序,和编写功能模块的。在编写程序时,所有的数据都是对结构体进行的操作,在此过程中,我发现了自己在对指针操作的时候,尤其是对指向结构体数组的指针和指向结构体的指针的操作都不够熟练。但在编写完此程序之后,我感觉自己对语法的应用有了明显的提高。七、参考书目:1、C程序设计(第三版) 谭浩强 清华大学出版社2、数据结构(C语言版)谭浩强 清华大学出版社3、程序设计基础(C语言版) 龙昭华 王玉柱 重庆大学出版社八、实验程序源代码#include#include#define null 0#define max 20#defin
20、e ok 1 struct record char date20; char operate20; int num; struct list_record char account20; char code20; char name20; int rec_len; struct record recmax;rmax; /系统原有数据,用户不可知int old_record( struct list_record r) int i; for(i=0;i3;i+) ri.rec_len=4; strcpy(r0.account,1001); strcpy(r1.account,1002); str
21、cpy(r2.account,1003); strcpy(r0.code,111111); strcpy(r1.code,222222); strcpy(r2.code,333333); strcpy(r0.name ,wang); strcpy(r1.name ,li); strcpy(r2.name ,zhang); strcpy(r0.rec0.date,07-01-01); strcpy(r0.rec1.date,07-02-01); strcpy(r0.rec2.date,07-03-01); strcpy(r0.rec3.date,07-04-01); strcpy(r1.rec0
22、.date,07-01-02); strcpy(r1.rec1.date,07-02-02); strcpy(r1.rec2.date,07-03-02); strcpy(r1.rec3.date,07-04-02); strcpy(r2.rec0.date,07-01-03); strcpy(r2.rec1.date,07-02-03); strcpy(r2.rec2.date,07-03-03); strcpy(r2.rec3.date,07-04-03); strcpy(r0.rec0.operate,in); strcpy(r0.rec1.operate,out); strcpy(r0
23、.rec2.operate,in); strcpy(r0.rec3.operate,out); strcpy(r1.rec0.operate,out); strcpy(r1.rec1.operate,in); strcpy(r1.rec2.operate,out); strcpy(r1.rec3.operate,in); strcpy(r2.rec0.operate,in); strcpy(r2.rec1.operate,out); strcpy(r2.rec2.operate,in); strcpy(r2.rec3.operate,out); r0.rec0.num=3000; r0.rec
24、1.num=-1500; r0.rec2.num=2500; r0.rec3.num=-1000; r1.rec0.num=-3000; r1.rec1.num=5000; r1.rec2.num=-1000; r1.rec2.num=2000; r2.rec0.num=1000; r2.rec1.num=-1500; r2.rec2.num=3000; r2.rec2.num=-500; return ok;/将数据写入文件void save( )FILE *fp; int i; if(fp=fopen(wenjian,wb)=null) printf(can not open the fi
25、le.n); return; for(i=0;imax;i+) if(fwrite(&ri,sizeof(struct list_record),1,fp)!=1) printf(file write error.n); fclose(fp);/文件读出void load( )FILE *fp; int i; if(fp=fopen(wenjian,rb)=null) printf(can not open infile.n); return; for(i=0;imax;i+) if(fread(&ri,sizeof(struct list_record),1,fp)!=1) if(feof(
26、fp) (fclose(fp); return; fclose(fp);/将用户输入的帐号与系统中原有帐号比较,查找用户帐号int lookup_accounts( struct list_record r,char acc) int i; for(i=0;i3;i+) if(strcmp(ri.account,acc)=0) return ok; printf(帐号不存在,请重新输入!n); return null; /检查密码函数 struct list_record check_code(struct list_record r,char acc,char c) int i; struc
27、t list_record a; strcpy(a.account,0); strcpy(a.code,0); a.rec_len=0; for(i=0;ia.rec_len;i+) strcpy(a.reci.date,0); strcpy(a.reci.operate,0); a.reci.num=0; for(i=0;iname); printf(帐号:%sn,(*p).account); /根据用户输入的日期,查找记录int find_record( struct list_record *p,char d) int i; for(i=0;i(*p).rec_len;i+) if(st
28、rcmp(*p).reci.date,d)=0) printf(date operate moneyn); printf(%s ,(*p).reci.date); printf(%s ,(*p).reci.operate); printf(%d n,(*p).reci.num); return ok; if(i=(*p).rec_len) printf(the date is not exit!n); return null; /插入函数,根据用户输入的信息,增加记录int insert_record( struct list_record *p,struct record *p1,int l
29、op) int i; if(lop(*p).rec_len+1) printf(the position is wrong.n); return 0; else for(i=(*p).rec_len;ilop-1;i-) strcpy(*p).reci.date,(*p).reci-1.date); strcpy(*p).reci.operate,(*p).reci-1.operate); (*p).reci.num=(*p).reci-1.num; strcpy(p-reci.date,p1-date); strcpy(*p).reci.operate,(*p1).operate); (*p
30、).reci.num=(*p1).num; (*p).rec_len+; return ok;/ 删除记录函数int del_record( struct list_record *p,int lop2) int i; if(lop2(*p).rec_len) printf(the position is wrong.n); return null; else for(i=lop2-1;i(*p).rec_len-1;i+) strcpy(*p).reci.date,(*p).reci+1.date); strcpy(*p).reci.operate,(*p).reci+1.operate);
31、 (*p).reci.num=(*p).reci+1.num; (*p).rec_len-; return ok; /输出全部记录函数 void all_print( struct list_record *p) int i; printf(date operate numn); for(i=0;i(*p).rec_len;i+) printf(%s ,(*p).reci.date); printf(%s ,(*p).reci.operate); printf(%d ,(*p).reci.num); printf(n); /计算总的钱数int sum_num( struct list_reco
32、rd *p) int i; int sum=0; int sum_in=0; int sum_out=0; for(i=0;i0) sum_in+=(*p).reci.num; if(*p).reci.num0) sum_out+=(*p).reci.num; printf(总金额为: %dn,sum); printf(总收入为: %dn,sum_in); printf(总支出为: %dn,sum_out); return ok;/输出收入记录int acc_print( struct list_record *p) int i; int sum_acc=0; printf(date oper
33、ate numn); for(i=0;i0) sum_acc+=(*p).reci.num; printf(%s ,(*p).reci.date); printf(%s ,(*p).reci.operate);printf(%d ,(*p).reci.num); printf(n); printf(总收入金额为: %dn,sum_acc); return ok; if(sum_acc=0) printf(there is no account.n); return null;/输出支出记录 int pay_print( struct list_record *p)int i; int sum_
34、pay=0; printf(date operate numn); for(i=0;irec_len;i+) if(*p).reci.num0) sum_pay+=(*p).reci.num; printf(%s ,(*p).reci.date); printf(%s ,(*p).reci.operate);printf(%d ,(*p).reci.num); printf(n); printf(总的支出为: %dn,sum_pay); return ok; if(sum_pay=0) printf(there is no payout.n); return null; void main(
35、) int j=0,n=0; int x,k,lop1,lop2; char data120; char accou20,cod20; struct record *p0; struct record a; struct list_record b; struct list_record *p; b.rec_len=0; p0=&a; old_record(r); save( ); load( ); printf( 欢迎使用个人财政支出管理系统!n); printf(-n); printf(| |n); printf(| 1、登陆系统 |n); printf(| 2、退出系统 |n); pri
36、ntf(| |n); printf(-n); scanf(%d,&x); if(x=0) printf( 感谢您使用本系统,再见!n); else do printf(请输入帐号:); /while(j3); scanf(%s,accou); if(lookup_accounts(r,accou) printf(请输入密码:); /while(j3) scanf(%s,cod); n+; while(n3); if(n=3) printf(您的密码不正确,请退出系统,谢谢使用,再见!n); break; else printf(-请选择您要进行的操作-n); printf(| |n); /while(j0) if(k=10) printf(感谢您使用本系统,再见!n); if(k=2) printf(请输入您要查询的日期:); scanf(%s,data1); find_record(p,data1); if(k=3) printf(请输入你要插入的位置:n); scanf(%d,&lop1); printf(请输入您要添加的记录:n); printf(日期:); scanf(%s,p0-date); printf(操作:); scanf(%s,p0-operate); printf(金额:); scanf(