问题的引入:
这学期C语言项目我选择做一个理财管理系统,数据存储使用链式映象,也在此基础上实现数据显示功能块。在完成了数据的统计显示,按时间段显示,按类别显示等功能后,才开始考虑数据的读写的文件操作功能块,因为自己之前几乎没有使用过C语言的文件操作函数。
2.如何解决:
有同学早早就完成了项目,我就抱大腿去学习下别人是如何实现的, 以下是同学做的学生成绩管理系统的读写操作函数(不过他是用顺序存储,惊了)
void IO_ReadInfo()
{
FILE *fp;
int i;
if ((fp=fopen("Database.txt","rb"))==NULL)
{
printf("error \n");
return;
}
if (fread(&num,sizeof(int),1,fp)!=1)
{
num=-1;
}
else
{
for(i=0;i
{
fread(&students[i],sizeof(struct student),1,fp);
}
}
fclose(fp);
}
void IO_WriteInfo()
{
FILE *fp;
int i;
if ((fp=fopen("Database.txt","wb"))==NULL)
{
printf("error\n");
return 0;
}
fwrite(&num,sizeof(int),1,fp);
for (i=0;i
{
fwrite(&students[i],sizeof(struct student),1,fp);
}
fclose(fp);
}
可看得我云里雾里,所以自己动手去实现功能之前,得需了解C语言的文件操作是通过哪些函数进行的,具体如何实现。
///1.打开操作
fopen(const char *, const char *);
///第一参数为文件名(绝对路径或相对路径),第二个参数为打开模式
/**********************************
打开模式 (打开二进制文件的模式需之前加一个'b')
"r":只能从文件中读数据,该文件必须先存在,否则打开失败
"w":只能向文件写数据,若指定的文件不存在则创建它,如果存在则先删除它再重建一个新文件
"a":向文件增加新数据(不删除原有数据),若文件不存在则打开失败,打开时位置指针移到文件末尾
"r+":可读/写数据,该文件必须先存在,否则打开失败
"w+":可读/写数据,用该模式打开新建一个文件,先向该文件写数据,然后可读取该文件中的数据
"a+":可读/写数据,原来的文件不被删去,位置指针移到文件末尾
*********************************/
///2.读写操作
fprintf(FILE *, const char *, ...);
fscanf(FILE *, const char *, ...);
///与printf和scanf的使用类似
///3.关闭操作
fclose(FILE *);
///关闭后将缓存区的信息写入磁盘
以上便是我需要使用到的函数。它们包含于stdio.h这个头文件中
3.问题解决:
既然有了工具,实现具体的链表读写操作就so easy了
void SaveJournal(LinkList* Inc,LinkList* Exp)///保存账目为txt文件到当前目录
{
FILE* Incomefile=fopen("Income.txt","w");
FILE* Expendfile=fopen("Expend.txt","w");
Link t_p=Inc->head;
while(t_p!=NULL)
{
fprintf(Incomefile,"%f %d %d %d %d ",t_p->mymoney[t_p->type],t_p->type,t_p->year,t_p->month,t_p->day);
t_p=t_p->next;
}
fclose(Incomefile);
t_p=Exp->head;
while(t_p!=NULL)
{
fprintf(Expendfile,"%f %d %d %d %d ",t_p->mymoney[t_p->type],t_p->type,t_p->year,t_p->month,t_p->day);
t_p=t_p->next;
}
fclose(Expendfile);
}
LinkList* LoadData(int opt) ///载入收入或支出账目
{
LinkList* L=(LinkList*)malloc(sizeof(LinkList));
L->len=0;
L->tail=L->head=NULL;
Link t_pr;
Link t_nx;
float t_money;
int t_type;
int t_year;
int t_month;
int t_day;
FILE* Incomefile=NULL;
FILE* Expendfile=NULL;
switch(opt)
{
case 1:
{
Incomefile=fopen("Income.txt","r");
while(fscanf(Incomefile,"%f %d %d %d %d ",&t_money,&t_type,&t_year,&t_month,&t_day)!=EOF)
{
t_pr=(Link)malloc(sizeof(DuLNode));
t_pr->type=t_type;
t_pr->mymoney[t_type]=t_money;
t_pr->year=t_year;
t_pr->month=t_month;
t_pr->day=t_day;
if(L->len>0)
{
t_pr->prior=t_nx;
t_nx->next=t_pr;
t_pr->next=NULL;
L->tail=t_pr;
t_nx=t_pr;
}
else
{
t_pr->prior=NULL;
t_pr->next=NULL;
L->head=L->tail=t_pr;
t_nx=t_pr;
}
L->len++;
}
fclose(Incomefile);
break;
}
case 2:
{
Expendfile=fopen("Expend.txt","r");
while(fscanf(Incomefile,"%f %d %d %d %d ",&t_money,&t_type,&t_year,&t_month,&t_day)!=EOF)
{
t_pr=(Link)malloc(sizeof(DuLNode));
t_pr->type=t_type;
t_pr->mymoney[t_type]=t_money;
t_pr->year=t_year;
t_pr->month=t_month;
t_pr->day=t_day;
if(L->len>0)
{
t_pr->prior=t_nx;
t_nx->next=t_pr;
t_pr->next=NULL;
L->tail=t_pr;
t_nx=t_pr;
}
else
{
t_pr->prior=NULL;
t_pr->next=NULL;
L->head=L->tail=t_pr;
t_nx=t_pr;
}
L->len++;
}
fclose(Expendfile);
break;
}
}
return L;
}
我将收入与支出信息分开来保存和读取,因为自己也是用两个双向链表存储收入和支出记录的。
4.拓展:
如何才能将收入和支出信息保存到同一文件中?如何区分呢?