1. 程式人生 > >C語言程式設計:圖書管理系統(超詳細有登入系統,附程式碼和試驗報告)

C語言程式設計:圖書管理系統(超詳細有登入系統,附程式碼和試驗報告)

C課程設計——圖書管理系統

1、題目意義

圖書館,作為文獻的聚集地和展示平臺,常常扮演著引領文化前進的角色,是每個大學不可或缺的基礎設施,而圖書管理系統則是一個圖書館能夠正常運轉的關鍵。本次課程設計使用C語言製作程式來實現圖書的登記,刪除,查詢,瀏覽以及讀者的借閱,還書,會員登入,修改密碼等功能。程式中涉及到資料鏈表和檔案指標的操作,包括結構體資料定義,使用及檔案的讀寫,定位,修改等。

2、設計思想

①新建賬號密碼,然後通過二者的匹配登入系統,這樣可以保證是本校同學才能使用,另外還可以修改密碼。 ②新增圖書的基本資訊,如 書號,書名,作者,出版社,類別,進庫量; ③刪除圖書,通過圖書的書名進行刪除; ④圖書查詢,通過圖書的書號,書名,作者或者類別進行檢索; ⑤瀏覽圖書的庫存,將所有數目展示出來; ⑥借書登記,先判斷是否有這本數,然後進行借書人學號,姓名,歸還截止期限,借書書名進行登記 ⑦還書情況檢視。 ⑧借閱情況檢視。 ⑨會員登入,通過資料檔案中的已註冊的賬號密碼來登入到圖書管理系統。 ⑩修改密碼

3.總設計框架圖

在這裡插入圖片描述

4.程式碼展示

#include <stdio.h>
#include <stdlib.h>//其中包含system函式
#include <conio.h>//定義了通過控制檯進行 資料輸入 和資料輸出的函式,如getch函式。
#include <string.h>//定義字元陣列
#include <math.h>
#define LEN sizeof(struct book)//有關圖書資訊的結構體
#define LEN1 sizeof(struct reader)//有關讀者資訊的結構體
#define LEN2 sizeof(struct land)//有關登入系統的結構體


struct book//圖書資訊
{
	char num[20],nam[20],aut[20],pub[20],cat[20];
	int  many;
	float price;
	struct book*next;
};

struct reader//讀者借閱資訊
{
	int jnum;
	char jnam[20],time[20],tsnam[20];
	struct reader *next;
};
struct land//登入資訊
{
	int zhanghao;
	char password[20];
	struct land*next;
};



int tjzs();//統計library文字個數函式
void xg(int,char[] );
void mainmenu();//顯示主選單
void tsmenu();//顯示圖書資訊選單
void jmenu();//顯示借閱資訊選單
void lmenu();//顯示登入選單

void main1();// 主選單功能
void tsmain();//圖書選單功能
void cxts();//查詢圖書
void zjts();//增加圖書
void scts();//刪除圖書
void llts();//瀏覽圖書

void jmain();//讀者借閱資訊
void js();//借書
void hs();//還書
void cxjs();//查詢借書
void lljs();// 瀏覽借書情況

void land();//登入功能系統
int xinjian(int,char[] );//建立賬號密碼
void xgmm();//修改密碼
void lmain();//登入介面函式


int tjzs()//統計圖書文字個數
{
FILE *fp;
int txcl=0,n;
float tprice=0;
char tname[20]={'\0'},tauthor[20]={'\0'},tchuban[20]={'\0'},tkind[20]={'\0'},tshuhao[20]={'\0'};
fp=fopen("library.txt","r");//開啟檔案
for (n=0;!feof(fp);n++)//逐個讀檔案
fscanf(fp,"%s%s%s%s%s%d%f",tshuhao,tname,tauthor,tchuban,tkind,&txcl,&tprice);
n--;
fclose(fp);//關閉檔案
return (n);//返回個數
}


int tjdzzs()//統計文讀者本個數函式

{
FILE *fp;
int zhenghao=0,n;
char mingzi[20]={'\0'},riqi[20]={'\0'},zname[20]={'\0'};
fp=fopen("reader.txt","r");//開啟檔案
for (n=0;!feof(fp);n++)//逐個讀檔案
fscanf(fp,"%d%s%s%s ",&zhenghao,&mingzi,&riqi,&zname);
n--;
fclose(fp);//關閉檔案
return (n);//返回個數
}


int tjzs3()//統計賬號密碼文字個數
{
FILE *fp;
int zhao=0,n;
char mm[20]={'\0'};
fp=fopen("land.txt","r");//開啟檔案
for (n=0;!feof(fp);n++)//逐個讀檔案
fscanf(fp,"%d %s",&zhao,mm);
n--;
fclose(fp);//關閉檔案
return (n);//返回個數
}


void mainmenu()//主選單
{
system ("cls");

printf("**************************************************");

printf("\n\n 1.圖書系統\n\n");

printf("\n\n 2.借閱系統\n\n");

printf("\n\n 3.退出系統\n\n");

printf("\n\n 請按鍵選擇,回車確定\n");

printf("*************************************************\n");

return ;
}


void tsmenu() //圖書館資訊選單
{
system ("cls");

printf("****************************************************");

printf("\n 1.增加圖書\n\n");

printf("\n 2.刪除圖書\n\n");

printf("\n 3.查詢圖書\n\n");

printf("\n 4.庫存瀏覽\n\n");

printf("\n 5.返回上一層\n\n");

printf("\n 請按鍵選擇,回車確定\n");

printf("***************************************************\n");

return ;

}


void main1()
{
	void tsmian();
	void jmain();
	char choose;
	mainmenu();
	scanf(" %c",&choose);
	switch(choose)//功能函式
  {
	  case'1':
	    tsmain();
	    break;
	  case'2':
	  	jmain();
	  	break;
	  case'3':
	  	system("cls");
    getch();
  	exit(0);
  	system ("cls");
	break;
  }
}


void tsmain()
{
	void zjts();
	void scts();
	void ctts();
	void llts();
	char choose;
	tsmenu();
	scanf(" %c",&choose);
	for(;;)
	{
		switch(choose)
	{
	case'1':
		zjts();
		break;
	case'2':
		scts();
		break;
	case'3':
		cxts();
		break;
	case'4':
		llts();
		break;
	case'5':
		main1();
		break;
	}
    }
}


void zjts()//增加圖書
{
	FILE*fp;
	char i;
	int many=0;
    float price=0;
    char  nam[20]={'\0'},aut[20]={'\0'},cat[20]={'\0'},pub[20]={'\0'},num[20]={'\0'};
    system ("cls");

    if ((fp=fopen("library.txt","r"))==NULL)//if語句:開啟圖書館檔案,不存在此檔案則新建
	{
      fp=fopen("library.txt","w");
      fclose(fp);
    }
	fp=fopen("library.txt","a");
	
	printf("\n請按以下格式輸入圖書資訊:\n書號 書名 作者 出版社 類別 進庫量 單價");
	
	for(;i!=27;)//為了實現輸入一次後按esc退出
	{
		printf("請輸入:\n");
		scanf("%s%s%s%s%s%d%f",num,nam,aut,pub,cat,&many,&price);
		fprintf(fp,"%-8s%-9s%-14s%-16s%-18s%-7d%-8.2f\n",num,nam,aut,pub,cat,many,price);
	    printf("繼續輸入請按回車,結束輸入請按Esc\n");
        i=getch();//暫停程式當i接收後繼續下一條指令
        for (;i!=13&&i!=27;)//保證只能是CR和ESC才能退出迴圈,輸入其他字元無用,暫停程式,按'CR'繼續。
        i=getch();
     }

	fclose(fp);
    printf("\n儲存成功,按任意鍵返回上一層!");
    getch();
	tsmain();//返回上一層
}

void scts()//刪除圖書
{
	   struct book *head=NULL;
       struct book *p,*p1,*p2;
       int tmany=0,n=0,j,k;
       float tprice=0;
       char  tnam[20]={'\0'},taut[20]={'\0'},tcat[20]={'\0'},tpub[20]={'\0'},tnum[20]={'\0'};
	   char jjnam[20]={'\0'};
	   char i;
       FILE *fp;
       if ((fp=fopen("library.txt","r"))==NULL)//開啟檔案
       {
	       system ("cls");
           printf("\n記錄檔案不存在!按任意鍵返回");
           getch();
           tsmain();
       }

	   else//實現刪除的功能
	   {
	      system ("cls");
	      printf("\n請輸入你要刪除的書名:");//輸入刪除圖書書名
          scanf("%s",jjnam);
          printf("\n確認刪除請回車,取消請按Esc\n");
          i=getch();
          for(;i!=13&&i!=27;)
          i=getch();
          if (i==27)
          tsmain();
	      fp=fopen("library.txt","r");
		 j=tjzs();

	   for (k=0;k<j;k++)
       {
	       fscanf(fp,"%s%s%s%s%s%d%f",tnum,tnam,taut,tpub,tcat,&tmany,&tprice);
           if (strcmp(jjnam,tnam))//比較名字,將不同名字的資訊複製到連結串列
          {
	          n++;//相同返回值為0不執行if語句繼續迴圈,不同則執行直到將所有不同的書名建立成連結串列
	            if (n==1)//建立連結串列
                {
		          p1=p2=(struct book*)malloc(LEN);
                  head=p1;
				}
                else
			    {
			      p2->next=p1;
				  p2=p1;
                  p1=(struct book*)malloc(LEN);//新建連結串列
                }

                strcpy(p1->num,tnum);//複製書號
                strcpy(p1->nam,tnam);//複製書名
                strcpy(p1->aut,taut);//複製作者名字
                strcpy(p1->pub,tpub);//複製出版社
                strcpy(p1->cat,tcat);//複製類別
                p1->many=tmany;//複製個數
                p1->price=tprice;//複製單價
           }
       }
             if (n==0)//如果圖書只有一項且這一項剛好和要刪除的相同
			 {
			 head=NULL;
			 }
			 else//建立連結串列的最後剩餘一個儲存空間,所以封底
			 {
			 p2->next=p1;
			 p1->next=NULL;
			 fclose(fp);
			 }
    }

   fp=fopen("library.txt","w");//清空檔案,只寫開啟,然後關閉
   fclose(fp);
   fp=fopen("library.txt","a");//追加檔案
   p=head;

   for (;p!=NULL;)//把連結串列內容覆蓋到檔案
   {
   	   fprintf(fp,"%-8s%-9s%-14s%-16s%-18s%-7d%-8.2f\n",p->num,p->nam,p->aut,p->pub,p->cat,p->many,p->price);
   	   p=p->next;
   }
   fclose(fp);
   system ("cls");
   printf("\n刪除成功 \n按任意鍵返回上一層\n");
   getch();//返回上一層
   tsmain();
}


void cxts()//查詢圖書
{
	   FILE *fp;
       int k=0,many=0,m=0,n=0;
	   float price=0;
       char  nam[20]={'\0'},aut[20]={'\0'},cat[20]={'\0'},pub[20]={'\0'},num[20]={'\0'};
       char i;
       char chazhao[20]={'\0'};
       if ((fp=fopen("library.txt","r"))==NULL)//開啟檔案
       {
	       system ("cls");
           printf("\n記錄檔案不存在!按任意鍵返回");
  		   getch();
		   tsmain();
       }
	   system("cls");
       printf("請輸入書號,書名,作者或類別查詢:\n");
       scanf("%s",chazhao);
       system ("cls");
       m=tjzs();

	   for (n=0;n<m;n++)
	   {
	    fscanf(fp,"%s%s%s%s%s%d%f",num,nam,aut,pub,cat,&many,&price);
        if(!strcmp(chazhao,num)||!strcmp(chazhao,nam)||!strcmp(chazhao,aut)||!strcmp(chazhao,cat))
        {
        	if(k==0)
            {
			  printf("查詢結果:\n\n");
			  printf("書號\t書名\t作者\t\t出版社\t\t類別\t\t現存量\t單價\n");
            }
			printf("%-8s%-9s%-14s%-16s%-18s%-7d%-8.2f\n",num,nam,aut,pub,cat,many,price);
            k++;
        }
       }
        if (k==0)//資料夾為空則輸出無記錄並返回上一層
        { system ("cls");
        printf("\n無符合記錄!\n");
        getch();
        tsmain();
		}
		fclose(fp);//查詢結束
		getch();
		tsmain();
}


void llts()//瀏覽圖書
{
	FILE *fp;
	int n=0;
       int k=0,m=0,many=0;
	   float price=0;
       char  nam[20]={'\0'},aut[20]={'\0'},cat[20]={'\0'},pub[20]={'\0'},num[20]={'\0'};
  	   char i;
	   if ((fp=fopen("library.txt","r"))==NULL)//開啟檔案
       {
	       system ("cls");
           printf("\n記錄檔案不存在!按任意鍵返回");
		   getch();//返回
           tsmain();
	   }
	   n= tjzs();
       if (n==0)
      {
	  system ("cls");
      printf("\n無任何記錄!");
      }

	     fp=fopen("library.txt","r");//開啟只讀檔案
         system ("cls");
	     printf("書號\t書名\t作者\t\t出版社\t\t類別\t\t庫存量\t單價\n");
  
	   for (m=0;m<n;m++)//輸出資料
	     {
	     fscanf(fp,"%s%s%s%s%s%d%f",num,nam,aut,pub,cat,&many,&price);
		 printf("%-8s%-9s%-14s%-16s%-18s%-7d%-8.2f\n",num,nam,aut,pub,cat,many,price);
	 	}
		fclose(fp);
        printf("\n按任意鍵返回\n");
        getch();
        tsmain();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`!~~~~~~~~~~~~~~~~~~~~~
	
void jmenu()//顯示借書選單
{
	system("cls");
	printf("*****************************************************");
	printf("\n\n 1.借書登記\n\n");
	printf("\n\n 2.還書登記\n\n");
	printf("\n\n 3.借閱情況檢視\n\n");
	printf("\n\n 4.查詢借書\n\n");
    printf("\n\n 5.返回上一層\n\n");
	printf("\n\n 請按鍵選擇,回車確定\n");
	printf("****************************************************");
	return ;
}


void jmain()//借閱系統函式
{
	void js();
	void hs();
	void lljs();
	void cxjs();
	char choose;
	jmenu();
	scanf(" %c",&choose);
	for(;;)
	{
		switch(choose)
		{
			case'1':
			js();
			break;
			case'2':
			hs();
			break;
			case'3':
			lljs();
			break;
			case'4':
			cxjs();
			break;
			case'5':
			main1();
			break;
		}
	}

}



void js()//借書函式
{
	FILE *fp,*fp3;
	struct book *head=NULL;
    struct book *p,*p1,*p2;
    int i,loop,k,n=0,flag=0,s=0;
	int jnum=0;
	int many=0;
	float tprice=0;
	char tname[20]={'\0'},tauthor[20]={'\0'},tchuban[20]={'\0'},tkind[20]={'\0'},tshuhao[20]={'\0'},
         ttname[20]={'\0'},mingzi[20]={'\0'},riqi[20]={'\0'},zname[20]={'\0'};
	char hit=0;

	system("cls");
	if((fp=fopen("library.txt","r"))==NULL)
	{
		system("cls");
		printf("\n 圖書館無庫存!按任意鍵退出!");
		getch();
		exit(0);
	}
	else
	{
        printf("\n請輸入借閱書名:\n請輸入:");
		scanf("%s",zname);
    k= tjzs();//統計圖書館檔案個數

	for (i=0;i<k;i++)//先將圖書資訊建立連結串列,更改庫存
    	{
    		fscanf(fp,"%s%s%s%s%s%d%f",tshuhao,tname,tauthor,tchuban,tkind,&many,&tprice);
			n++;
			if(n==1)
			{
				p1=p2=(struct book*)malloc(LEN);
				head=p1;
			}
		    else
           	{
                p2->next=p1;
                p2=p1;
                p1=(struct book*)malloc(LEN);

            }
			strcpy(p1->num,tshuhao);//複製書號
			strcpy(p1->nam,tname);//複製書名
			strcpy(p1->aut,tauthor);//複製作者
			strcpy(p1->pub,tchuban);//複製出版社
			strcpy(p1->cat,tkind);//複製類別
			p1->many=many;//複製現存量
			p1->price=tprice;//複製單價
        }
        if(n==0)
 		head=NULL;
		else
		 {
		 	p2->next=p1;
		 	p1->next=NULL;
		 	fclose(fp);
		 }

	}
	p=head;
	
	for (;p!=NULL;)
	{
		if(!(strcmp(p->nam,zname)))//判斷要借書的是否存在,標記等於1,存在庫存減一
		{
			
            flag=1;
		 	loop=p->many;
		 	(p->many)--;
		 }
			p=p->next;
  }
	if(flag&&(loop>0))//存在被借的圖書且現存量大於0,把庫存量變化後的連結串列存入檔案
    {

		fp=fopen("library.txt","w");
    	fclose(fp);
    	fp=fopen("library.txt","a");
    	p=head;

		for(;p !=NULL;)
    	{
    		fprintf(fp,"%-8s%-9s%-14s%-16s%-18s%-7d%-8.2f\n",p->num,p->nam,p->aut,p->pub,p->cat,p->many,p->price);
   		   	p=p->next;
		}
		free(p);
		fclose(fp);

		if ((fp3=fopen("reader.txt","r"))==NULL)//建讀者資料夾存入借書資訊
        {
		    fp3=fopen("reader.txt","w");//開啟只讀檔案
            fclose(fp3);
        }
		fp3=fopen("reader.txt","a");

		printf("\n請按以下格式輸入讀者資訊:\n 證號 姓名 借書日期 借書書名\n請輸入:");//錄入讀者資訊
 		scanf("%d %s %s %s",&jnum,mingzi,riqi,zname);
		fprintf(fp3,"\n%-8d%-23s%-18s%-10s\n",jnum,mingzi,riqi,zname);
	    fclose(fp3);
        printf("借書成功!請兩個月內歸還!!!按任意鍵返回\n");
		getch();//返回
		jmain();//呼叫借閱系統
   }
	else
    {
    	if(flag!=0)
        printf("此書已被借完!按任意鍵返回!");//否則輸出此書已被借完
		else
		printf("查詢無此書!按任意鍵返回");
	}
	    getch();//返回
        jmain();//呼叫借閱系統

}


void hs ()//還書函式
{
 	 FILE *fp,*fp3;
	 struct reader *head=NULL;
	 struct reader *p,*p1,*p2;
	 struct book *lhead1=NULL;
	 struct book *zp1,*lp1,*lp2;
	 int txcl=0,i;
	 float tprice=0;
	 char tname[20]={'\0'},tauthor[20]={'\0'},tkind[20]={'\0'},
	 tchuban[20]={'\0'},ttname[20]={'\0'},tshuhao[20]={'\0'};
	 int ttzhenghao=0,tzhenghao=0,n=0,k=0,t=0,flag=0;
	 char tmingzi[20]={'\0'},triqi[20]={'\0'},tzname[20]={'\0'},ttzname[20]={'\0'};
	 char hitkey=0;
	 system ("cls");
{
 	 if ((fp=fopen("reader.txt","r"))==NULL)//不存在讀者檔案,則輸出不能還書
	  {
         system ("cls");
		 printf("\n 不存在借書者!按任意鍵退出!");
		 getch();
		 system("cls");
		 jmain();
      }

	  else
	  {{
	     printf("\n請輸入讀者證號和書名:\n請輸入:");
		 scanf("%d %s",&ttzhenghao,ttzname);//輸入還書證號和書名
		 k=tjdzzs();//獲取讀者資料夾資訊個數
		 for (i=0;i<k;i++)//讀取讀者資料夾資訊
           {
			fscanf(fp,"%d%s%s%s\n ",&tzhenghao,tmingzi,triqi,tzname);
			if((ttzhenghao==tzhenghao)&&!strcmp(ttzname,tzname))//如果證號書名存在,則標記為1
			flag=1;
			}
      fclose(fp);
	  fp=fopen("reader.txt","r");//開啟讀者檔案,刪除借書資訊
	  if(flag)
	  {
	  for (i=0;i<k;i++)//將讀者檔案複製到連結串列
	  {
	  fscanf(fp,"%d%s%s%s\n ",&tzhenghao,tmingzi,triqi,tzname);//讀取檔案資訊
	  if(!((ttzhenghao==tzhenghao)&&!strcmp(ttzname,tzname)))
	  {
          n++;
		  if (n==1)
		  {
		      p1=p2=(struct reader*)malloc(LEN1);//新建連結串列
			  head=p1;
		  }
		  else
		  {
		        p2->next=p1;
				p2=p1;
				p1=(struct reader*)malloc(LEN1);//新建連結串列
          }
		  p1->jnum=tzhenghao;//複製證號
		  strcpy(p1->jnam,tmingzi);//複製讀者名字
		  strcpy(p1->time,triqi);//複製日
		  strcpy(p1->tsnam,tzname);//複製書名
		  }}
		  if (n==0)
		  head=NULL;
		  else
		  {
		       p2->next=p1;
			   p1->next=NULL;
			   fclose(fp);
	      }
		  fp=fopen("reader.txt","w");//清空讀者檔案
		  fclose(fp);
		  fp=fopen("reader.txt","a");//追加資訊
		  p=head;
		  for (;p!=NULL;)//把連結串列內容覆蓋讀者檔案
		  {
		      fprintf(fp,"\n%-8d%-23s%-18s%-10s\n",p->jnum,p->jnam,p->time,p->tsnam);
			  p=p->next;
	      }
		  free(p);
		  fclose(fp);
		  }}}}

		  if(flag)//標記為1,即還書時更改庫存
		  {{
		  {
		      printf("確認還書請按回車!");
			  for (;hitkey!=13&&hitkey!=27;)
			  hitkey=getch();
			  if (hitkey==13)
			  printf("成功!按任意鍵返回!");
			  n=0;flag=0;
			  fp3=fopen("library.txt","r");//開啟圖書館檔案
			  k=tjzs();//獲取圖書館檔案個數
			  for (i=0;i<k;i++)//將圖書館檔案複製到連結串列
			  {
			       fscanf(fp3,"%s%s%s%s%s%d%f",tshuhao,tname,tauthor,tchuban,tkind,&txcl,&tprice);//讀取資訊
				   n++;
				   if (n==1)
				   {
				       lp1=lp2=(struct book*)malloc(LEN);//新建連結串列
					   lhead1=lp1;
				   }
				   else
				   {
				       lp2->next=lp1;
					   lp2=lp1;
					   lp1=(struct book*)malloc(LEN);//新建連結串列
				   }
				   strcpy(lp1->num,tshuhao);//複製書號
				   strcpy(lp1->nam,tname);//複製書名
				   strcpy(lp1->aut,tauthor);//複製作者
				   strcpy(lp1->pub,tchuban);//複製出版社
				   strcpy(lp1->cat,tkind);//複製類別
				   lp1->many=txcl; //複製現存量
				   lp1->price=tprice;//複製單價
				   }
				   if (n==0)
				   {
 	  		          lhead1=NULL;
				   }
				   else
				   {
				   	   lp2->next=lp1;
				   	   lp1->next=NULL;
				   	   fclose(fp3);
				   }}}
				   zp1=lhead1;
				   for (;zp1!=NULL;)
				   {
				        if(!(strcmp(zp1->nam,ttzname)))//尋找書名相同
						++(zp1->many);//現存量加1
						zp1=zp1->next;
					}
					fp3=fopen("library.txt","w");//清空圖書館檔案
					fclose(fp);
					fp3=fopen("library.txt","a");//追加資訊
					zp1=lhead1;
					for (;zp1!=NULL;)//把連結串列內容覆蓋圖書館檔案
					{
                         fprintf(fp3,"%-8s%-9s%-14s%-16s%-18s%-7d%-8.2f\n",
        				 zp1->num,zp1->nam,zp1->aut,zp1->pub,zp1->cat,zp1->many,zp1->price);
						 zp1=zp1->next;
				    }
					fclose(fp3);
					getch();//返回
					jmain();//呼叫借閱系統
					}
					else
					printf("不存在此資訊!按任意鍵返回!");
					getch();//返回
					jmain();//呼叫借閱系統
}


void lljs()//顯示借書情況函式

{
    FILE *fp;
    int zhenghao=0,xcl=0,n=0,i=0,j=0;
    char mingzi[20]={'\0'},riqi[20]={'\0'},zname[20]={'\0'};
	if ((fp=fopen("reader.txt","r"))==NULL)//開啟讀者資料夾
    {
        system ("cls");
        printf("\n記錄檔案不存在!按任意鍵返回");
	    getch();
	    jmain();
    }
    n=tjdzzs();
    if (n==0)
	{ system ("cls");
	printf("\n無任何記錄!");
	}
	fp=fopen("reader.txt","r");
	system ("cls");
	printf("\n證號\t讀者姓名\t\t借書日期\t書名\n");
	for (;!feof(fp);)//輸出檔案資訊
	{
	fscanf(fp,"%d%s%s%s\n ",&zhenghao,mingzi,riqi,zname);
	printf("\n%-8d%-23s%-18s%-10s\n", zhenghao,mingzi,riqi,zname);
	}
	fclose(fp);
	printf("\n按任意鍵返回\n");
	getch();//返回
	jmain();//呼叫借閱系統
}

					
void cxjs()//查詢借書
{
	   FILE *fp;
       int jsnum=0,k=0,many=0,m=0,n=0;

       char  jsnam[20]={'\0'},jstime[20]={'\0'},tsnam[20]={'\0'};
       char i;
       char chazhao[20]={'\0'};
       if ((fp=fopen("reader.txt","r"))==NULL)//開啟檔案
       {
	       system ("cls");
           printf("\n記錄檔案不存在!按任意鍵返回");
  		   getch();
		   jmain();
       }
	   system("cls");
       printf("請輸入證號或姓名查詢:\n");
       scanf("%s",chazhao);
       system ("cls");
	   m=tjzs();
	   for (n=0;n<m;n++)
	   {
	    fscanf(fp,"%d%s%s%s",&jsnum,jsnam,jstime,tsnam);
        if(!strcmp(chazhao,jsnam)||(('chazhao'-'0')==jsnum))
        {
        	if(k==0)
            {
			  printf("查詢結果:\n\n");
			  printf("\n證號\t讀者姓名\t\t借書日期\t書名\n");
            }
			printf("\n%-8d%-23s%-18s%-10s\n",jsnum,jsnam,jstime,tsnam);
            k++;
         }
       }
	    if (k==0)//資料夾為空則輸出無記錄並返回上一層
        { system ("cls");
        printf("\n無符合記錄!\n");
        getch();
        jmain();
		}
       fclose(fp);//查詢結束
		getch();
		jmain();
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

void lmenu()//顯示登入選單
{


printf("\n\n\t    歡迎使用會員登入系統\n\n");
printf("**********************************************");
printf("\n\n\t\t1.登入系統\n\n");
printf("\n\n\t\t2.建立賬號\n\n");
printf("\n\n\t\t3.修改密碼\n\n");
printf("\n\n\t\t4.退出系統\n\n");
printf("\n\n\t    請按鍵選擇,回車確定\n");
printf("**********************************************");
return ;
}


void lmain()//登入功能函式
{
	void land();
	void xinjian();
	char choose;
	lmenu();
	scanf(" %c",&choose);
	switch(choose)//功能函式
  {
	  case'1':
	    land();
	    break;
	  case'2':
	  	xinjian();
	  	break;
	  	case'3':
	  	xgmm();
	  	break;
	  case'4':
	  	system("cls");
    getch();
  	exit(0);
  	system ("cls");
	break;
  }
}



void xinjian()//新建賬戶密碼
{
	FILE *fp;
	int zhanghao;
	char password[20],password1[20];
	char hit=0;
	if ((fp=fopen("land.txt","r"))==NULL)//if語句:開啟圖書館檔案,不存在此檔案則新建
	{
      fp=fopen("land.txt","w");
      fclose(fp);
    }
    system("cls");
	fp=fopen("land.txt","a");
	for(;;)//輸入兩次密碼確認,兩次相同才能確認
	{
	   printf("\n請按以下格式輸入賬戶:\n學號 密碼\n");
	   printf("請輸入:");
	   scanf("%d %s",&zhanghao,password);
       printf("再次輸入密碼:\n");
	   scanf("%s",password1);
	   if(strcmp(password,password1)==0)
	   {
	       fprintf(fp,"%d %s\n",zhanghao,password);
		   break;
       }
       else
	   {
	       printf("兩次輸入密碼不一致,繼續建立按回車,退出按ESC");
	       hit=getch();
		   if(hit=27)
		   system("cls");
		   lmain();
		         }
   }
   fclose(fp);
   printf("建立成功,按任意鍵返回");
   getch();
   system("cls");
   lmain();
}



int match(int m,char a[20])//匹配資料庫中的賬號密碼
{
	FILE*fp;
	int n=0,i=0;
	int zhanghao;
	char password[20];

	if ((fp=fopen("land.txt","r"))==NULL)//不存在讀者檔案
	  {
         system ("cls");
		 printf("\n 還未存在使用者!請新建賬戶");
		 getch();
	 	system("cls");
		lmain();
	
      }


        for(;!feof(fp);)
      {
        fscanf(fp,"%d%s",&zhanghao,password);
        if(m==zhanghao)
        {
        	if(strcmp(a,password)==0)
			return 1;
			else
			{
			return -1;
		   }
	    }
	  }
	  return 0;
 }

void land()//輸入賬戶密碼的登入函式
{
	int zhanghao;
	char password[20];
	int i=2,j,k,n;
	char hit=0;
	system("cls");
	do
	{
	   printf("\n請輸入賬號:\n");
       scanf("%d",&zhanghao);
       printf("確認輸入請安回車,重新輸入請按ECS");
       hit=getch();//暫停程式當i接收後繼續下一條指令
       for (;hit!=13&&hit!=27;)//保證只能是CR和ESC才能退出迴圈,輸入其他字元無用,暫停程式,按'CR'繼續。
       {
	        hit=getch();
	   }
    }
    while(hit==27);
	 printf("\n請輸入密碼:\n");
	 scanf("%s",password);
     i=match(zhanghao,password);
     if(i==1)
	 {
       printf("登陸成功!按任意鍵繼續");
	   getch();
	   main1();
	 }
	 else
	 {
	 	if(i==-1)
		 {
		 printf("密碼錯誤!");
		 getch();
         land();
		 }
		 if(i==0)
		 printf("不存在此使用者");
		 getch();
		 system("cls");
		 lmain();
	 }
}

void xg(int z,char m[20])//修改函式
{
	FILE *fp;
	int zhanghao1,n,j,k;
	char mima1[20];
	struct land *head,*p,*p1,*p2;

	 fp=fopen("land.txt","r");
	   j =tjzs3();

	   for (k=0;k<=j;k++)
       {
	       fscanf(fp,"%d %s",&zhanghao1,mima1);
           if (z!=zhanghao1)//比較名字,將不同名字的資訊複製到連結串列
          {
	            n++;//相同返回值為0不執行if語句繼續迴圈,不同則執行直到將所有不同的書名建立成連結串列
	            if (n==1)//建立連結串列
                {
		          p1=p2=(struct land*)malloc(LEN2);
                  head=p1;
				}
                else
			    {
			      p2->next=p1;
				  p2=p1;
                  p1=(struct land*)malloc(LEN2);//新建連結串列
                }
 				p1->zhanghao=zhanghao1;
                strcpy(p1->password,mima1);//複製賬號密碼
          }
       }
        if (n==0)
			 {
			 head=NULL;
			 }
			 else//建立連結串列的最後剩餘一個儲存空間,所以封底
			 {
			 p2->next=p1;
			 p1->next=NULL;
			 fclose(fp);
			 }
			  fp=fopen("land.txt","w");//清空檔案,只寫開啟,然後關閉
              fclose(fp);
              fp=fopen("land.txt","a");//追加檔案
              p=head;
            for (;p!=NULL;)//把連結串列內容覆蓋到檔案
   			{
   	   		 	fprintf(fp,"%d %s%\n",p->zhanghao,p->password);
   	   			p=p->next;
	        }
	        fprintf(fp,"%d %s\n",z,m);
            fclose(fp);
             system ("cls");

}



void xgmm()//修改密碼
{

	   FILE *fp;
       int zh=0,k=0,many=0,m=0,n=0;
       int chazhao,hit;
       char mima[20]={'\0'},password1[20]={'\0'};
       char  mm[20]={'\0'};
       char i;

       if ((fp=fopen("land.txt","r"))==NULL)//開啟檔案
       {
	       system ("cls");
           printf("\n記錄檔案不存在!按任意鍵返回");
  		   getch();
  		   system("cls");
		   lmain();
       }
	   system("cls");
       printf("請輸入你的帳號和舊密碼:\n");
       scanf("%d %s",&chazhao,mima);
	   m =tjzs3();
	   for (n=0;n<=m;n++)
	   {
	    fscanf(fp,"%d %s",&zh,mm);
        if(zh==chazhao)
        {
        	if(!strcmp(mm,mima))
        	{
        		printf("請輸入新的密碼");
        		scanf("%s",mima);
       		    printf("再次輸入密碼:\n");
	            scanf("%s",password1);
	             if(strcmp(mima,password1)==0)
	   			 {
		             xg(chazhao,mima);
		            getch();
				    lmain();
	                system("cls");
   			     }
       			  else
	   			  {
	       		   	  printf("兩次輸入密碼不一致,按任意鍵退出");
	       			  hit=getch();
		   			  system("cls");
				      lmain();

   				  }
			}
			else
			{
				printf("舊密碼錯誤,按任意鍵返回!");
				getch();
				system("cls");
				lmain();
	            
			}

        }
      }
	   printf("不存在此賬號,按任意鍵返回");
		fclose(fp);//修改結束
		getch();
		system("cls");
		lmain();
}



int main()
{
	system("color 1F");
	lmain();
	return 0;
}

5.遇到的難點及解決辦法

(1)不知道如何停止程式,以及只讓程式在ESC和回車按下後才繼續工作。 解:查閱資料getch() 所在標頭檔案:conio.h 函式用途:從控制檯讀取一個字元,但不顯示在螢幕上 函式原型:int getch(void) 返回值:讀取的字元 程式碼: for(;i!=13&&i!=27;) i=getch();

(2)不知道C語言未初始化的變數的值,導致無限迴圈。 解:全域性變數 、靜態變數初始值為0 區域性變數,自動變數初始值隨機分配

(3)不知道如何快速清理檔案和新建檔案 解:查閱覽書本後知道,先只寫檔案,如果檔名和已存在的相同,那麼就會先刪除原有檔案,而且如果不存在檔案將會之間新建檔案。 fp=fopen(“library.txt”,“w”); \清空 fclose(fp); if ((fp=fopen(“library.txt”,“r”))==NULL)//快速新建 { fp=fopen(“library.txt”,“w”); fclose(fp); }

(4)對a!=2和a=!2弄混淆 解:a!=2:表示a不等於“2”; a=!2:表示a等於“!2”(0);

(5)編譯正確,但是有的時候scanf語句好像沒有執行,輸入資料回車,程式沒反應 解:查閱得知: 這種情況通常發生在前面已經有了輸入語句,而當前的scanf是在接收字元(即用%c控制輸入)時。由於前面的輸入語句(不一定是scanf)把最後輸入的’\n’遺留在了輸入緩衝區,而當前的scanf("%c",…);又會把’\n’當一個字元接收,又由於scanf在%c控制下只接收一個字元,所以就不能接收正式輸入的字元了。解決這一問題的最簡單辦法是在接收字元的scanf的控制符"%c"中的%前加一個空格寫成" %c",把前一次輸入遺留在輸入緩衝區裡的所有廣義空格(’ ‘、’\t’、’\n’等)都吸收掉。在接收字元的scanf前加getchar()等的辦法其實是有漏洞的——當緩衝區裡只遺留了一個廣義字元時可正常工作,若多於一個則同樣出錯。 按回車沒反應

(6),關於“feof”的誤區 For(;!feof(fp)?; n++; n–;來判斷檔案裡面字元的個數為什麼錯誤, 查閱得知: 1.EOF EOF是一個計算機術語,為End Of File的縮寫,在作業系統中表示資料源無更多的資料可讀取。資料源通常稱為檔案或串流。通常在文字的最後存在此字元表示資料結束。這個定義的意思是,文件的結尾都有一個隱藏字元”EOF”,當程式讀取它的時候,就會知道檔案已經到達結尾。通常使用while迴圈加EOF判斷作為讀取結束的標誌。 EOF 的值通常為 -1,但它依系統有所不同。 2.feof() feof()的原理: feof()函式,並不是通過讀取到檔案的EOF來評判,這個檔案是否為空。 對feof()來說,它的工作原理是,站在游標所在位置,向後看看還有沒有字元。如果有,返回0;如果沒有,返回非0。它並不會讀取相關資訊,只是檢視游標後是否還有內容。 直接使用時的錯誤分析: 對於一個空檔案來說,當程式開啟它的時候,它的游標會停在檔案的開頭,但是由於檔案裡什麼內容都沒有存(但是EOF是存在的),即整個檔案就存貯了一個EOF。當程式開啟檔案,並直接呼叫feof()時,這個函式就會站在游標的位置向後張望,結果就看見了EOF,然後就當然返回0了。所以使用feof()函式時,必須要讀取檔案,讓游標移動。

(7)錯因:用正確的格式寫入檔案,結果卻沒有資料 解:沒有及時fclose(fp),不彌補資料儲存的原理。 開啟檔案fopen函式把返回值賦給fp,用fclose關閉檔案,如果不關閉檔案就結束程式將會丟失資料,因為,在向檔案裡面寫入資料時,是先將資料輸入到緩衝區,待緩衝區從滿後才正式輸出給檔案。因此用fclose函式關閉檔案時,先把緩衝區中的資料輸出到磁碟檔案,然後才撤銷檔案資訊區。