日记管理系统
简单工资表格式-
关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
福
建
工
程
学
院
实
验
报
告
专
业
计算机科学与技术
班
级
计算机
1001
座
号
姓
名
日
期
2012/5/14
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
福建工程学院计算机与信息科学系
实验报告
2010
–
2011
学年第
一
学期
任课老师:
章静
日记管理系统的开发
实验开始日期:
20120503
实验时间
报告提交日期:
20120514
实验目的、要求
实验题目
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
一、
实验题目:
设计一个简单实用个人日记管理系统。
二、实验要求
1
.该实验的课内学时是
4
个课时。
2
.程序完成后应该完成如下基本功能:
1
)用自定义日记的存储结构,每篇日记至少包含日期,内
容等字段;
2
)使用者必须输入密码;
3
)写日记与保存功能;
4
)日记查阅:按日期查看,按关键字查看,按顺序查看功能(从某一篇开
始)
3
.在
完成上述基本功能的前提下,有能力的同学可以完成如下加强功能:
1
)实现日记的永久存储。
2
)对保存的密码进行变换,以免泄密。
3
)允许多人使用。
4
)在程序的提示语言清晰明确,界面美观并且适用。
实验设计内容
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
(
1
)实验设计的数据结构
/*
定义日记结点类型
*/
typedef struct Diary
{
char date[15];
/*
日期
*/
char title[20];
/*
日记标题
*/
int flag;
/*<
/p>
判断日记是否符合查阅要求,是为
0
,否
为
-1*/
struct Diary *next;
}Diary;
< br>/*
定义用户结点类型
*/
typedef struct User
{
char name[20];
/*
用户名
*/
char password[20];/*
登录密码
*/
int
count;
p>
/*
该用户拥有的日志的个数
*/
Diary *first; /*
指向用户拥有的日记链表的表头
*/
struct User *next;
}*Us,User;
最后的用户信
息以及在该用户目录下的日志信息以二进制的形式存在文件中。
(
2
)总体函数模块结构图:
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
用户登陆和注册
写入日记
日
志
管
理
系统
日记查询
按顺序查询
按日期查询
日记删除
按照关键字查询
用户、日记信息保存
初始化用户、日志信息读取
密码修改
(3)
重点函数分析
1.
初始化函数:程序运行会运行此函数,讲已有的用户信息和她们的日志信息
读入链表中。
Us
Init()
{
FILE *fp1,*fp2;
Us L=NULL;
User
*p;
Diary *s;
if ((fp1=fopen(
return L;
while(!feof(fp1))
{
p=(User
*)malloc(sizeof(User));
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
if(fread(p,sizeof(User),1,fp1)!=1)
break;
//
从一
个流中读取数据
(接受数据
的指针,单个元素的大小,元素个数
,提供数据的文件指针)
p->first=NULL;
//
读取系统已有的用户信息
p->next=L;
L=p;
chdir(p->name);
//
把相应用户目录作为当前工作目录
if((fp2=fopen(
continue;
}
else
while(!feof(fp2))
{
s=(Diary
*)malloc(sizeof(Diary));
//<
/p>
读取系统相应用户的相
应日记信息
if(fread(s,sizeof(Diary),1,fp2)!=1)
break;
s->next=L->first;
p>
//first
为该用户的节点拥有的日志链表
L->first=s;
}
fclose(fp2);
p>
//
关闭存储日志信息的文件,把父目录作为当前工作目录
}
fclose(fp1);
return(L);
}
2.
登录
结构流程图:
页脚内容
关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
输入用户名及其对应密码
N
开始
<
/p>
判
断
输
入
的
用
户
名
和
密
码
链
Y
进入日志操作
代码:
/*
用户登录函数
*/
void
Login(Us L)
{
char temp[20];
char flag;
int
i,j,count;
User
*p;
Diary *s;
p=L;
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
system(
printf(
pri
ntf(
用户登入
t|n
printf(
pri
ntf(
已有的用户名
:n
printf(
printf(
序号
t
用户名
tt|n
count=1;
while(p!=NULL)
//
将已经有的用户名和对应序号打
印出来
{
printf(
%stt|n
p=p->next;
count++;
}
printf(
count--;
pri
ntf(
输入序号
:tt
i=Input_Integer();
//<
/p>
这样我们在选择序号时输入字符也不会造成死循环
while(i>count||i==-1)
{
printf(
< br>输入序号错误
pri
ntf(
是否继续进行输入
:(Y or N)
scanf(
if(flag=='N'||flag=='n')
return;
pri
ntf(
输入序号
:tt
scanf(
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
}
j=1;
p=L;
while(j
{
j++;
p=p->next;
}
printf(
你选择的用户
:tt%s
printf(
输入密码
:tt
Password_input(temp);
//
输入密码
Express_chage_dark(temp);
p>
//
明码转化为暗码,
以跟以保存的用户<
/p>
密码比较
while(strcmp(p->password,te
mp)!=0)
{
printf(
< br>输入的密码错误
!!!n
printf(
是否继续输入
:(Y
or N)t
scanf(
if
(flag=='N'||flag=='n')
return;
printf(
< br>输入密码
:tt
Password_input(temp);
Express_chage_dark(temp);
}
printf(
登入中
,
请稍等
.....
system(
User_Operate(p,L);
//
用户登入后,进行用户操作
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
}
3.
用户注册:
结构流程图:
开始
输入要注册的用户名
Y
检
查
p>
该
用
户
是
否
已
N
输入密码(密码确
N
两
次
输
入
密
码
Y
注册成功
代码:
/*
新用户申请函数
*/
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
Us
User_apply(Us L)
{
char
temp1[20];
char
temp2[20];
int
i;
char flag;
User *p;
User *s;
rewind(stdin);
s=(User
*)malloc(sizeof(User));
system(
printf(
pri
ntf(
申请用户
t|n
printf(
pri
ntf(
已有的用户名
:n
p=L;
while(p!=NULL)
{
printf(
p=p->next;
//
输出
系统已存在的用户
名,以让用户申请新用户时,有个注意,不申请重复的用户名
}
p=L;
printf(
< br>输入用户名
:tt
scanf(
rewind(stdin);
whi
le(p!=NULL&&strcmp(p->name,s->name)!=0)
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
p=p->next;
//
判断有没有
重复的用户名
while(p!=NULL)
{
printf(
< br>该用户名已经存在
!!!!!n
p>
printf(
是否继续进行申请用户
:(
Y or N)
scanf(
if
(flag=='N'||flag=='n')
{
free(s);
return L;
}
printf(
< br>输入用户名
:t
scanf(
rewind(stdin);
p=L;
while(p!=NULL&&
strcmp(p->name,s->name)!=0)
p=p->next;
}
pri
ntf(
该用户名可以使用
n
printf(
输入密码
:tt
Password_input(temp1);
printf(
确认密码
:tt
Password_input(temp2);
while(strcmp(temp1,temp2)!=
0)
{
printf(
两次输入的密码不一
致
!!!n
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
p>
printf(
输入密码
:tt
Password_input(temp1);
printf(
确认密码
:tt
Password_input(temp2);
}
strcpy(s->password,temp1);
s->first=NULL;
s->count=0;
//
申请好用户,
mkdir(s->name);
//<
/p>
生成相应用户对应的文件夹,文件夹里
用来存储相应用户的相应日
记
Express_chage_dark(s->password);
//
进行密码家秘密
s->next=L;
L=s;
Save_user(L);
p>
getchar();//
每添加一个用户时,都要进行存储用户信
息的保存
pri
ntf(
申请中
,
请稍等
.....
pri
ntf(
申请成功!
nnt
getchar();
return(L);
}
4.
写日志操作:
< br>说明:
在次用户登陆后,打开文件,直接找到该用户目录下的日志表单,将写入的
日志直
接写到这个人的用户的文件夹中,
日志具体内容并不是保
存在链表中的,
由于考录到日志内容
可能会很长,这样可以节省
空间。
函数结构流程图:
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
开始
输入日记内容、日记
打开文件
fp=fopen
讲日记内容写入到文件中
保存更新后的用户信息
代码:
/*
写日记
*/
void
Write_dairy(User *H,Us L)
{
int
choice;
char temp[200];
//
用于存储写入的日记
FILE *fp;
Diary *s;
int
i;
printf(
输入日记内容
:nntt
scanf(
getchar();
rewind(stdin);
Express_chage_dark(temp);
//
对日记内容加密
s=(Diary *)malloc(sizeof(Diary));
//
为保存日志的节点动态申请空间
p>
printf(
输入要保存的日记名
:t<
/p>
页脚内容
关
于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
scanf(
getchar();
rewind(stdin);
whi
le(Search_dairy(H,s->title)!=1)
{
printf(
< br>该日记名已经存在,请重新输入
!!!!
p>
printf(
重新输入要保存的日记名
:
t
scanf(
getchar();
}
printf(
< br>该日记名可以使用
pri
ntf(
输入日期时间
:(20120501)t
scanf(
getchar();
rewind(stdin);
s->flag=0;
chdir(H->name);
//
把相应用户目录作为当前工作的
目录
(
因为日志
信息是直接放在文件中
的,每次对日志内容添加、修改是都要先打开文件
)
if((fp=fopen(s->title,
{
printf(
< br>对不起
,
不能打开文件
!!!<
/p>
return;
}
i=0;
p>
printf(
保存中
,
< br>请稍等
.....
while(temp[i]!='0')
{
页脚内容
关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
fwrite(temp+i,1,1,fp);
//<
/p>
将信息写入文件流中
(要输出数据的地址,
要读写
的字节数,要读写的字节数据的个数,文件类型的指针)
i=i+1;
}
s->next=H->first;
//
头插法,新写的日志排在最前面
H->first=s;
H->count++;
fclose(fp);
Save_dairy(H);
//
保存相应用户的日记信息
Save_user(L);
//
保存用户信息,因为此时用户的
count
已经改变了,需要保存
p>
printf(
保存完毕
!nnt
}
4.
查阅日记操作
函数流程图:
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
开始
选择查询方式
按顺序查询
按关键字查询
按日期查询
输出日记
返回
代码:
/*
查阅日记
*/
void
Consult_dairy(User *H,int i)
{
Diary *p;
FILE *fp;
char
temp[200];
int j;
int
flag=0;
//
先进行遍遍历,
若有找到符合条件的日志则做标记
p=H->first;
if
(i==-1)
//
进行顺序查询
{
p>
printf(
请输入要顺序查看的日记序号
:t
页脚内容
< br>关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
scanf(
if(j<=H->count)
{
while(j>1)
{
p=p->next;
j--;
}
p->flag=-1;
//<
/p>
找到符合条件日记,对应结点的
flag
赋为
-1
,以便待会筛选出来
flag=1;
//
在此
用户的日志链表中有找到过符合条件的日志
}
}
else
{
if (i==0)
printf(
输入要查询的日期<
/p>
:t
//
进行日期查询
if (i==15)
printf(
输入要查询的关键字
:t
进行关键字查询
scanf(
rewind(stdin);
while(p!=NULL)
{
if(strstr((p->date+i),temp)!=NULL)
//
分配的空间是连续的
{ p->flag=-1;
//
找到符合条件的结点,其
flag
赋予
-1
,
以便待会筛选出来
flag=1;
//
在此用户的日志链表中有找到过
符合条件的日志
}
p=p->next;
}
页脚内容
关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
}
if(flag==0)
printf(
对不起
,
找不到所需要的日记
else
{
p=H->first;
printf(
要查看的日记如下<
/p>
n
chdir(H->name);
//
把相
应用户的目录弄为当前工作目录(要对文件进行操作)
while(p!=NULL)
{
if(p->flag==-1)
//
先前找到的符合条件的日子打印
出来
{
printf(
—————————
————————————————————————
n
printf(
< br>日记名
:%stt
时间
%sn<
/p>
p->flag=0;
//
筛选输出结点的
flag
为
-1
的日记名,日
期
Read_dairy(p->title);
}
p=p->next;
}
}
printf(
}
5.
删除用户日记
函数流程图:
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
代码:
/*
删除用户日记
*/
void
Delete_dairy(User *H,Us L)
{
Diary *p;
//
指向要删除的结点
Diary *pre;
//
指向要删除的结点的前驱结点
int
i,j;
char flag;
printf(
请输入要删除的日记
序号
:tt
scanf(
rewind(stdin);
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
j=i;
p=H->first;
//
先找到要进行删除的结点
if(j<=H->count)
//
先判
断一下输入的药删除日志的编号是否小于该用户拥有的总日志
的个数
{
while(i>1)
{
p=p->next;
i--;
}
p->flag=-1;
//<
/p>
要删除的结点的
flag
标识符设为
p>
-1
p=H->first;
//
再对找到的结点进行删除操作
while(p!=NULL&&(p->flag==0))
{
pre=p;
p=p->next;
}
p>
printf(
要删除的日记是
:n
printf(
序号
:%dt
日记名
:
%st
时间
:%s
getchar();
printf(
是否确认要删除
:(Y
or N) t
scanf(
rewind(stdin);
if(flag=='Y'||flag=='y')
{
if(H->first==p)
H->first=p->next;
//
要删除的结点为第一结点时
else
pre->next=p->next;
//<
/p>
要删除的结点不是第一
页脚内容
关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
结点时
}
else
return
chdir(H->name);
//
把相应用户的目录弄为当前工作
目录
H->count--;
p>
//
用户的日记数减
1
remove(p->title);
//
去掉相应的文件
free(p);
//
释放要删除的结点空间
Save_dairy(H);
//<
/p>
保存用户日记信息,
不然原有的用户日记
信息还是不变
Save_user(L);
//
保存用户信息
printf(
< br>删除中
,
请稍等
.....
p>
pri
ntf(
删除成功
!!!nt
}
else{
p>
printf(
序号太大
n
}
}
p>
7
.用户及其拥有的日志信息在文件中的保存
/*
保存用户日记信息
*/
void
Save_dairy(User *H)
{
FILE
*fp;
Diary *p;
chdir(H->name);
p>
//
把相应用户目录作为当前工作目录
(<
/p>
用
于文件操作)
if((fp=fopen(
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
{
p>
printf(
输入有误
:
不能打开文件!
n
return;
}
p=H->first;
while(p!=NULL)
{
fwrite(p,sizeof(Diary),1,fp);
//
将信
息写入文件流中(要输出数据的地址,要读
写的字节数,要读写的字节数据的个数,文件
类型的指针)
p=p->next;
}
fclose(fp);
}
/*<
/p>
保存全部用户日记信息
*/
void Save_user(Us L)
{
FILE *fp;
User *p;
fp=fopen(
p=L;
while(p!=NULL)
{
fwrite(p,sizeof(User),1,fp);
p=p->next;
}
fclose(fp);
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
}
调试过程记录
(feof(fp)==0)
{
页脚内容
关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
fwrite(fp,
i++;
}
p>
本系实验主要是考察队文件的运用,而我一开始对文件这一部分的编程比较陌生,在经过看书
查阅各种资料
后,对其的一些知识有所了解,经过实验中的反复运用加以熟练。例如通过
实验代码的反复测试我发现了:
Fwrite
写入的是一个数据块,
fscanf
一个一个的输入,这边只能用
fscanf
实验结果记录以及与预期结果比较以及分析
1.
主界面
2.
用户注册界面
页脚内容
关于日照经济开发区供水公司关于在新区兴建供水水厂项目的请示的批复
3.
用户操登陆
4.
登陆后菜单:
4.1
写日志功能:
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
4.2
查看自己日志:(按顺序查找)
4.3
查看好友日志:(按日期查找)
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
4.4
删除日志:
4.5
更改密码:
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
总结以及心得体会
这次实验综合考察了链表和文件的操作,
有一定的复杂性。在实验的训练中,一
开始拿到
题目没有什么思路主要是不明白日志具体要实现什么功能,
然后要实现的这些功能又要用什么
样的函数来构成。
然后通
过查阅有关资料,
看人家的成平的具体结构在思想中有了大体的结构
才开始一个功能一个功能的实现的编写。而日志管理系统的编写中最主要的就是文件的运用,
在这里我的我们用户所写的日志并不存在用户的日志链表中,
而是直接写入文件
,
读取的时候
是通过日志的名称找到那一个日志的文件,
然后打开文件直接从文件中读取并显示出来。
这样
么可以节省很多的空间,
因为用户的日志的长度有长有短,
如果日志的内容页存在日志的链表
中会真用很大空间,造成浪费现象,而且用户输入的日
志长度还会有所限制。考虑到这些,就
采用直接将用户的日志内容存在文件中的方法了。
总之,在日志系统的编写中,不仅对链表的使用更加熟练也加
强了文件这一部分的运用。
同时也十分感谢老师在实验过程中给予的耐心指导。
指导老师评阅意见
页脚内容
关于日照经济开发区供水公
司关于在新区兴建供水水厂项目的请示的批复
指导老师:
年
月
日
整体代码:
/*
日记
管理系统
*/
#include
#include
#include
#include
#define Enter 13
//
回车键
/*
定义日记结点类型
*/
typedef struct Diary
{
char date[15];
/*
日期
*/
char title[20];
/*
日记标题
*/
int flag;
/*<
/p>
判断日记是否符合查阅要求,是为
0
,否
为
-1*/
struct Diary *next;
}Diary;
< br>/*
定义用户结点类型
*/
typedef struct User
{
char name[20];
/*
用户名
*/
char password[20];/*
登录密码
*/
页脚内容