
程序将文件与链表结合;
#include
#include
#include
#include
#include
#include
#include
//#define var 333;
//移动光标位置
void gotoxy(int x,int y)
{
COORD xy;
HANDLE hstdout;
hstdout=GetStdHandle(STD_OUTPUT_HANDLE);//设置一个句柄
xy.X=x;//定义横坐标
xy.Y=y;//定义纵坐标
SetConsoleCursorPosition(hstdout,xy);//设置控制台光标位置
//CloseHandle(hstdout);
}
void fillchar(char a,int charlen)
{
COORD xy={0};
HANDLE hstdout;
long byw;
hstdout=GetStdHandle(STD_OUTPUT_HANDLE);
FillConsoleOutputCharacter(hstdout,a,charlen,xy,&byw);
CloseHandle(hstdout);
}
#define X 20
#define Y 6
//绘制边框
void drawM(void)
{
int i;
//上边
gotoxy(X,Y);
printf("┏");
for (i=1;i<=27;i++)
{
printf("━");
}
printf("┓");
//左边
for (i=1;i<=16;i++)
{
gotoxy(X,Y+i);
printf("┃");
}
//右边
for (i=1;i<=16;i++)
{
gotoxy(X+28,Y+i);
printf("┃");
}
//下边
gotoxy(X,Y+17);
printf("┗");
for (i=1;i<=27;i++)
{
printf("━");
}
printf("┛");
return ;
}
//绘制菜单
void drawmenu(void)
{
gotoxy(X+3,Y+3);
printf("1->查看现有图书");
gotoxy(X+3,Y+3+2);
printf(" 添加新图书");
gotoxy(X+3,Y+3+2+2);
printf(" 学生借书");
gotoxy(X+3,Y+3+2+2+2);
printf(" 学生还书");
gotoxy(X+3,Y+3+2+2+2+2);
printf(" 查看借书记录");
gotoxy(X+3,Y+3+2+2+2+2+2);
printf(" 退出");
gotoxy(0,0);
}
int selmenu_Num=0;
int selmenu(void)
{
//如果按下↓selmenu_Num++; 如果>6 selmenu_Num=0;
//如果按下↑selmenu_Num--; 如果<0 selmenu_Num=2;
int i;
int ch=0;
while(1)
{
ch=getch();
//gotoxy(0,0);
//printf("%d ",ch);
if (ch==13)
{
return selmenu_Num;
}
switch(ch)
{
case 72://上光标
selmenu_Num--;
if (selmenu_Num<0)
{
selmenu_Num=6;
}
break;
case 80: //下光标
selmenu_Num++;
if (selmenu_Num>6)
{
selmenu_Num=0;
}
break;
}
gotoxy(0,0);
//printf("selmenu_num=%d",selmenu_Num);//测试按上下键后传递的参数是否改变
//动态菜单
switch(selmenu_Num)
{
case 0:
for(i=0;i<6;i++)
{
gotoxy(X+3,Y+3+2*i);
if(i==0)
printf("1->");
else
printf(" ");
}
gotoxy(0,0);
break;
case 1:
for(i=0;i<6;i++)
{
gotoxy(X+3,Y+3+2*i);
if(i==1)
printf("2->");
else
printf(" ");
}
gotoxy(0,0);
break;
case 2:
for(i=0;i<6;i++)
{
gotoxy(X+3,Y+3+2*i);
if(i==2)
printf("3->");
else
printf(" ");
}
gotoxy(0,0);
break;
case 3:
for(i=0;i<6;i++)
{
gotoxy(X+3,Y+3+2*i);
if(i==3)
printf("4->");
else
printf(" ");
}
gotoxy(0,0);
break;
case 4:
for(i=0;i<6;i++)
{
gotoxy(X+3,Y+3+2*i);
if(i==4)
printf("5->");
else
printf(" ");
}
gotoxy(0,0);
break;
case 5:
for(i=0;i<6;i++)
{
gotoxy(X+3,Y+3+2*i);
if(i==5)
printf("6->");
else
printf(" ");
}
gotoxy(0,0);
break;
case 6:
for(i=0;i<6;i++)
{
gotoxy(X+3,Y+3+2*i);
if(i==6)
printf("7->");
else
printf(" ");
}
gotoxy(0,0);
break;
}
} //end while
return selmenu_Num;
}
//定义图书
struct book{
char bookname[20];//书名
int NO;//书号
char type[20];//类型
};
//定义学生
struct student{
char name[10];//姓名
char classes[20];//班级
int number;//学号
struct book b;
};
//定义学生结点
typedef struct SNode{
struct student data;
struct SNode *next,*previous;
}SNode,*SList;
//自定义图书链表
typedef struct LNode{
struct book data;
struct LNode *next,*previous;
}LNode,*LList;
//添加图书
void addBook()
{
FILE *fp;//创建文件类型的指针
struct book b;//创建自定义的book类型
int i,j;
if(((fp=fopen("shuku.txt","a")))==NULL){//以添加写入的形式打开文件
printf("File open error!\n");
exit(0);
}
printf("输入书的总数:");
scanf("%d",&i);
for(j=0;jdata.bookname=NULL;
H->data.NO=NULL;
*H->data.type=NULL;*/
if((fp=fopen("shuku.txt","r"))==NULL){
printf("不能打开此文件!\n");
exit(0);
}
while(!feof(fp)){
L = (LNode * )malloc(sizeof(LNode));
if (L==NULL)
{
printf("申请内存空间失败.");
L->next=NULL;
}
fscanf(fp,"%s%d%s",L->data.bookname,&L->data.NO,L->data.type);
T->next=L;
L->next=NULL;
L->previous=T;
T=L;
}
if(fclose(fp)){
printf("不能够关闭文件");
exit(0);
}
return H;
}
void LListToFile(LList L)//将书库记录链表转换为书库记录文件
{ FILE *fp;
if((fp=fopen("shuku.txt","w"))==NULL){
printf("不能打开此文件!\n");
exit(0);
}
L=L->next;
while(L->next!=NULL){
fprintf(fp,"%20s%20d%20s",L->data.bookname,L->data.NO,L->data.type);
L=L->next;
}
if(fclose(fp)){
printf("不能够关闭文件");
exit(0);
}
}
void SListToFile(SList L)//将借书记录链表转换为借书记录文件
{ FILE *fp;
if((fp=fopen("jieshujilu.txt","w"))==NULL){
printf("不能打开此文件!\n");
exit(0);
}
L=L->next;
while(L->next!=NULL){
fprintf(fp,"%20s%20s%20d%20s%20d%20s",L->data.name,L->data.classes,L->data.number,L->data.b.bookname,L->data.b.NO,L->data.b.type);
L=L->next;
}
if(fclose(fp)){
printf("不能够关闭文件");
exit(0);
}
}
SList FileToSList()//将借书记录信息转换为链表
{ FILE *fp;
SNode *H,*T,*L;
struct book p;
H=T = (SNode * )malloc(sizeof(LNode));
/**H->data.b.bookname=NULL;
H->data.b.NO=NULL;
*H->data.b.type=NULL;
*H->data.classes=NULL;
*H->data.name=NULL;
H->data.number=NULL;*/
if((fp=fopen("jieshujilu.txt","r"))==NULL){//以读的形式打开文件
printf("不能打开此文件!\n");
exit(0);
}
while(!feof(fp)){
L = (SNode * )malloc(sizeof(SNode));//在内存中开辟结点那么大的空间
if (L==NULL)
{
printf("申请内存空间失败.");
L->next=NULL;
}
fscanf(fp,"%s%s%d%s%d%s",L->data.name,L->data.classes,&L->data.number,L->data.b.bookname,&L->data.b.NO,L->data.b.type);
//将文件中的姓名、班级、学号、书名、书号、类型、依此导入链表
T->next=L;
L->next=NULL;
L->previous=T;
T=L;
}
if(fclose(fp)){
printf("不能够关闭文件");
exit(0);
}
return H;
}
//借书操作,新建借书学生信息
void new_student(LList L){
int result=0;
FILE *fp;
struct student p;
char choice;
if(((fp=fopen("jieshujilu.txt","a"))==NULL)){
printf("文件打开错误!!!!\n");
exit(0);
}
printf("输入借书人姓名:");
scanf("%s",&p.name);
printf("输入借书人班级:");
scanf("%s",&p.classes);
printf("输入借书人学号:");
scanf("%d",&p.number);
result = MessageBox( NULL , TEXT("确认是否借书") , TEXT("借书") , MB_ICONINFORMATION|MB_YESNO);//设置窗口点击是进行删除;否不进行操作
if(result==IDYES)/*注意!使用Unicode应用TEXT包围字串*/
{
fprintf(fp,"%s\t",p.name);
fprintf(fp,"%s\t",p.classes);
fprintf(fp,"%d\t",p.number);
fprintf(fp,"%s\t%d\t%s\t",L->data.bookname,L->data.NO,L->data.type);
}
if(fclose(fp)){
printf("不能够关闭文件");
exit(0);
}
}
SList ReturnBook(SList S){
int no;
int result;
FILE *fp;
SList s;
s=S;
printf("输入归还书的书号:");
scanf("%d",&no);
printf("确认信息:");
while(S->next!=NULL){
if(S->data.b.NO==no)
{
printf("借书人姓名:%s\t借书人班级:%s\t借书人学号%d\n所借书书名%s\t所借书书号:%d\t所借书类型:%s\n",S->data.name,S->data.classes,S->data.number,S->data.b.bookname,S->data.b.NO,S->data.b.type);
result = MessageBox( NULL , TEXT("是否还书") , TEXT("还书") , MB_ICONINFORMATION|MB_YESNO);//设置窗口点击是进行删除;否不进行操作
if(result==IDYES)/*注意!使用Unicode应用TEXT包围字串*/
{
if(((fp=fopen("shuku.txt","a"))==NULL)){
printf("文件打开错误!!!!\n");
exit(0);
}
fprintf(fp,"%20s%20d%20s\n",S->data.b.bookname,S->data.b.NO,S->data.b.type);
if(fclose(fp)){
printf("不能够关闭文件");
exit(0);
}
}
S->previous->next=S->next;
}
S=S->next;
}
return s;
}
void broowBook(LList T)
{ int no;
LNode *H,*p;
H=p=T;
H=H->next;
printf("输入所要借书的书号:");
scanf("%d",&no);
while(H!=NULL){//显示图书信息
if(H->data.NO==no)
{
printf("图书名称:%s\n",H->data.bookname);
printf("图书书号:%d\n",H->data.NO);
printf("图书类型:%s\n",H->data.type);
printf("再次确认所借图书的图书号:");
scanf("%d",&no);
new_student(H);
H->previous->next=H->next;
}
H=H->next;
}
LListToFile(p);//将书库链表转换为书库文件
}
//查看书库
void see_book(){
FILE *fp;
int NO;
char bookname[20];
char type[20];
if((fp=fopen("shuku.txt","r"))==NULL){//以只读的形式打开文件
printf("文件打错误!!!");
exit(0);
}
printf("***************库存图书****************");
while(!feof(fp))//显示全部库存图书
{
fscanf(fp,"%s%d%s",bookname,&NO,type);
printf("\n书名:%s\t书号:%d\t类型:%s\n",bookname,NO,type);
};
if(fclose(fp)){
printf("不能够关闭文件!!!");
exit(0);
}
getchar();
}
//查看借书记录
void see_student()
{
FILE *fp;
SList s;
s=FileToSList()->next;//因为是带头结点的链表所以要将下一个有值得结点地址赋给s;
while(s->next!=NULL)
{
printf("姓名:%s\t班级:%s\t学号:%d\n图书书名:%s\t图书书号:%d\t图书类型:%s\n",s->data.name,s->data.classes,s->data.number,s->data.b.bookname,s->data.b.NO,s->data.b.type);
s=s->next;
}
}
int main(void)
{
LList H;//创建图书
SList S,s;
int sel;
system("color 0a");//设置文字颜色
system(" title 图书馆管理系统");//设置标题
while(1){
getchar();//按下回车后执行清屏;同时绘制菜单
system("cls");//清屏函数
drawM();
drawmenu();
sel=selmenu();
system("cls");
switch(sel)
{
case 0:gotoxy(0,6);see_book();break;//查看书库
case 1:gotoxy(0,6);addBook();break;//添加书库
case 2:gotoxy(0,6);H=FileToLList();broowBook(H);break;//学生借书
case 3:gotoxy(0,6);S=FileToSList();s=ReturnBook(S);
SListToFile(s);
break;//学生还书
case 4:gotoxy(0,6);see_student();break;//查看借书记录
case 5:exit(0);break;//退出程序
}
}
getchar();//从键盘接受一个字符在进行退出
return 0;
}