我们既然想要完成一个记账簿,那么首先就要考虑需要实现哪些具体的功能。首先一个记账簿需要有以下基础功能
1.记账 2.查询 3.修改 4.删除 5.退出。记账功能又可以分为1.收入 2.支出,查询功能可以分为,1.查询余额 ,2.查询总收入,3.查询总支出,4.查询总账单。我们现在一一进行功能的实现。
一.菜单和选择,退出机制
首先是菜单的制定,根据上面的分析我们可以想到,这里应该需要三个菜单,一个主菜单,一个记账菜单,还有一个查询菜单
然后利用do-while和switch实现一个选择不同操作的功能
int main()
{
int input=0;
do
{
main_mnus();
printf("请选择:>");
scanf_s("%d", &input);
switch (input)
{
case 1:
mnus1();choose1(&acc);
break;
case 2:
mnus2(); choose2(&acc); break;
case 3:
break;
case 4:
break;
case 0:
printf("退出成功\n"); break;
default:printf("输入错误,请从新输入\n"); break;
}
} while(input);
}
之后需要对记账和查询单独在做一个选择操作的功能
//注意上述函数之后会挨个实现
二.创建记账溥
因为一条账单信息会有很多元素,所以我们需要创建一个结构体变量。首先我们要想,一条记账信息要有那些元素,第一要知道这是一条收入账单还是支出账单,这里我们用一个简单的办法定义一个flag标记收入或支出,1代表支出,0代表收入。第二如果是支出账单,那么我们需要知道这笔钱的去向,所以我们需要一个字符数组,来记录这笔钱的去向,如果是收入账单,我们需要知道这笔账单的来源,做法和支出一样。第三,我们需要知道这笔账单的具体金额,第四,为了方便之后查找,我们这里给每个账单都做一个标记,第五,我们要知道这条账单的时间。
到这里,我们就完成了每一条账单该有的信息,但是记账簿还没有完成,既然是记账簿,就要有存储的功能,这里我们再创建一个结构体,用来表示记账簿,定义一个Account_book*
指针(记账信息结构体重新命名后的名字),来记录每条记账信息,然后还需要一个变量来表示,当前总共有多少条记账信息,最后再用一个变量来表示,记账簿的共容量有多少方便之后进行扩容
//这里为了方便之后修改数组大小我们用define定义各个数组大小
三.初始化记账溥
首先需要将,记账簿内信息记为零,设置初始化最大容量,之后calloc一个(创建最大容量个大小为sizeof(Account_book))的空间,之后再将第一个数据序号定位1
//这里的flag是为了之后更好的储存新加的数据,之后会在讲Load(acc)是一个加载之前的数据的函数,之后一一实现现在先不用管。
//再calloc之后不要忘了判断是否开辟成功
四.记账功能
现在我们准备工作已经做完了,开始正式来实现一些功能
1.记录收入
首先我们先设定一个标头,为了方便让我们知道这是一条收入账单,之后开始,记录这条账单的信息,为了排版好看,这里我们就先记录账单的日期,然后输入金额,最后再输入这笔账单的来源,因为这是一笔收入账单,不会存在使用的去向,所以我们直接把使用设为空格,之后将flag设为一,表示这是一条收入账单,最后,我们需要知道这条账单的序号,我这里是直接让该条账单的序号等于上一条账单的序号加一,最后再将count+1表示记录了一条账单(这种方法有一个问题,必须要有一个初始序号,所以之前再初始化时直接将第一条账单定为一)。
2.记录支出
记录支出的方法和记录收入的方法差不多,但是有一些不同,为了方便我们之后查看,我们记录过的账单,这里我们将支出账单的金额设定为负数,方便区分支出和收入账单。
//不过,既然到了这里我们难免会考虑一个问题,要是容量不够了怎么办?
3.扩容
首先,我们需要先判断,需不需要扩容,判断的方法其实很简单,就是看当前的记账信息,是否已经达到最大容量,如果达到最大容量的话,那就进行扩容,没有达到就不用。然后我们来进行扩容的操作,利用realloc函数,来增加我们所创建的空间大小至于每次扩容多大的空间,可以按自己的想法来我这里,选择的是一次性扩容和初始大小一样的空间。
//扩容之后要记得让最大容量也增加相应大小
//将ptr置为空指针是为了防止之后有可能通过ptr再找到这片空间,造成错误
//再realloc之后不要忘了判断是否开辟成功
到了这里我们的记账功能已经完成了!
五.查询功能
1.查询余额
这个功能相对较简单,只需要将所有账单遍历一遍,然后将金额相加就行(因为之前已经把支出定义为负数,所以直接加和就行)
//余额要定义为double类型
2.查询收入账单
之前已近将支出和收入做了区分所以现在只要找到记账溥中flag是1的账单打印就行。
//注意收入账单要打印的是来源
3.查询支出账单
支出和收入的方法如出一辙
//注意支出账单要打印的是用处
4.查询总账单
打印总账单,整体思路和打印收入账单以及支出账单差不多,只不过要加一条判断语句,首先遍历整个记账簿,判断要打印的该条记账信息,是支出还是收入,然后再按照相应的打印方式进行打印就可以。
//注意支出和收入的打印方式不同
到这里我们的查询功能也已经完成了!
六.修改和删除
再实现功能之前,我们可以先想一想,如果要修改或删除某一条数据的话,是不是就要先找到这个数据,所以我们先实现一个查找序号的功能。
1.查找序号
我这样的不懂,是你个最简单的查找方法,直接从头遍历一遍,找到自己所要查询的那个数据的序号,返回其下标就好了。这种方法无疑效率是非常低下的,所以大家可以使用一些其他更高效的查找方式。
//找到返回下标,没找到返回-1
2.修改
修改方式比较简单,就是首先找到要修改的那条账单,然后重新输入一遍就可以了,输入方法和上面的一样。
3.删除
首先还是要先找到需要删除的对象,找到之后就删除这条数据,删除的方法就是,令这条数据之后的所有数据向前移动一个单位,这样做既可以将要删除的数据覆盖掉,还可以让删除后的序号依然是连续的。
//不要忘记让count-1
七.保存
再输入完数据之后,我们需要将数据保存在一个文件中,利用fopen函数,创建一个文件并将数据保存进去,这里我用的是二进制写入,也可以用一些其他的方式进行保存。
如果用"a"的形式进行追加存入,每次存入数据时不会覆盖之前的数据,所以,每次存入数据要从之前的数据的最后(也就是之前再初始化时的flag)开始向后存储,每次只存入新的数据。而且支出数据要先存use因为use是需要的数据,source是" "放在后面不影响查看,存入数据要先存source因为source是需要的数据,use是" "放在后面不影响查看。
//在fopen之后要记得检查是否打开成功
//在最后要记得关闭文件
八.加载数据
我们的每次打开记账簿的时候,都需要知道之前的账单,所以需要一个加载数据的功能,其实就是将我们存入文件里的数据,读到我们的记账簿中。因为我们是用二进制写进去的,所以在读的时候也需要以二进制的方式读取,首先还是利用fopen函数打开文件,这里我们需要定义一个中间变量,将数据复制到账单中。最后用 red函数,进行依次读取,在读取的时候也可能会存在空间不够的情况,所以当空间不够时,也需要扩容。
//fread函数,在读取到数据时会返回一
//在fopen之后要记得检查是否打开成功
//在最后要记得关闭文件
九.销毁空间
在最后结束退出之前要记得把空间释放掉
十.源码分享
1.text.c
2.Account_book.h
3.Account_book.c
以上是根据我个人写出的一个c语言记账溥的功能,其中也会存在一些不足,相信大家会有其他更简单方便的方法来进行一些功能的实现,欢迎在下方留言讨论。