본문 바로가기
카테고리 없음

내가 만든 도서관리 프로그램

by Ryan Kim 2015. 4. 12.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<Windows.h>

//기본적으로 책식별자, 책이름, 저자, 가격)
typedef struct node_data{

 int iden;
 char bookname[50];
 char writer[20];
 int price;
}N_data;

typedef struct node{
 
 struct node_data nd;
 struct node *next;

}Node;

typedef struct linkedlist{
 
 Node *head;
 Node *cur;
 Node *before;
 int numofdata;
 int (*comp)(int iden1, int iden2);

}List;

void ListInit(List *list);
void SearchBook(List *list);
int SearchBookFirst(List *list,int *num);
int SearchBookNext(List *list,int *num);
void BookList(List *list);
void BookInsert(List *list);
void BookFix(List *list);
void BookDeletion(List *list);
void ProgramClose(List *list);
void FBookInsert(List *list, N_data data);
void SBookInsert(List *list,N_data data);
void SetSortRule(List *list, int (*comp)(int iden1, int iden2));
int WhoIsPrecede(int iden1, int iden2);
void ShowData(List *list);
void FixData(List *list);
void DeletionData(List *list);
void GetDataFromFile(List *list);

int main(void){

  
  int chosen_num;
  List list;
  ListInit(&list);
  

  printf("#############################################################################################################\n");
  printf("#\t\t\t\t\t\t\t\t\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t도서관리 프로그램\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t made by. 김승우\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t\t\t\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t 1.도서 검색\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 2.도서 목록\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 3.도서 등록\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 4.도서 수정\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 5.도서 삭제\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 6.프로그램 종료\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 7.화면 청소하기\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t\t\t\t\t\t\t\t        #\n");
  printf("#############################################################################################################\n");
  
  while(1){
  printf("\n원하시는 기능을 선택해주세요(숫자):");
  scanf("%d",&chosen_num);
  
  switch(chosen_num){
  case 1:
   SearchBook(&list);
   break;

  case 2:
   BookList(&list);
   break;

  case 3:
   BookInsert(&list);
   break;

  case 4:
   BookFix(&list);
   break;
 
  case 5:
   BookDeletion(&list);
   break;

  case 6:
   ProgramClose(&list);
   exit(1);
   break;

  case 7:
   system("cls");
  printf("#############################################################################################################\n");
  printf("#\t\t\t\t\t\t\t\t\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t도서관리 프로그램\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t made by. 김승우\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t\t\t\t\t\t\t\t        #\n");
  printf("#\t\t\t\t\t\t 1.도서 검색\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 2.도서 목록\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 3.도서 등록\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 4.도서 수정\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 5.도서 삭제\t\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 6.프로그램 종료\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t 7.화면 청소하기\t\t\t\t\t\t    #\n");
  printf("#\t\t\t\t\t\t\t\t\t\t\t\t\t        #\n");
  printf("#############################################################################################################\n");
   break;
  
  default:
   printf("숫자를 잘못 입력하였습니다. 다시 입력해주세요.!! \n\a");
   break;
  }
  
  }
  
  return 0;

}
            

 void ListInit(List *list){

  
  list->head =(Node*)malloc(sizeof(Node));
  list->head->next=NULL;
  list->comp=NULL;
  SetSortRule(list, WhoIsPrecede); //정렬기능을 제공하는 함수
  GetDataFromFile(list);
 
 }
 //처음에 파일로부터 데이터를 얻음
 void GetDataFromFile(List *list){
  
  //char *string;
  int flag=0;
  FILE* stream;
  N_data bookdata={0,NULL,NULL,0};
  stream=fopen("bookdata.txt","r");

  if(stream==NULL){
  return;
  }
  
  while(1){
  
  flag=fscanf(stream,"%d %d\n",&bookdata.iden,&bookdata.price);
  fgets(bookdata.bookname,sizeof(bookdata.bookname),stream);
  fgets(bookdata.writer,sizeof(bookdata.writer),stream);
  //fgets()함수는 뒤에 개행문자도 포함하므로 개행문자를 공백문자로 바꿔준다.
  bookdata.bookname[strlen(bookdata.bookname)-1]='\0';
  bookdata.writer[strlen(bookdata.writer)-1]='\0';
 
   //printf("%d%s%s%d\n",bookdata.iden,bookdata.bookname,bookdata.writer,bookdata.price);
  if(flag != EOF){
  
  if(list->comp==NULL){
   FBookInsert(list,bookdata);
   //printf("hello12");
  }
  else{
   SBookInsert(list,bookdata);
  }
  }
  
  else
   return;
  }

  fclose(stream);
 
 }

 //책 찾기 함수
 void SearchBook(List *list){

  int sbnum;
  int indexnum;
  int num;
  printf("찾고자 하는 책의 식별번호를 입력해주세요:");
  scanf("%d",&sbnum);


  if( SearchBookFirst(list, &num)){
  
   if(num==sbnum){
   ShowData(list);
   return;
   }
  }
  
  while(SearchBookNext(list,&num)){

   if(num==sbnum){
   ShowData(list);
   return;
   }
  }


  printf("찾으시고자 하는 데이터가 없습니다. 빠른 시일내에 재입고나 구매요청을 하겠습니다.\n");
  return;
   
  }

 //도서 목록을 출력하는 함수
 void BookList(List *list){

  Node *nd=list->head->next;
  if(nd==NULL){
   printf("죄송하지만, 아직은 등록된 책이 없습니다. 조금만 기다려주시기 바랍니다.!!\n");
   return;
  }
     printf("식별번호 \t\t       도서 이름       \t\t    저자 이름   \t가격\n");
  while(nd != NULL){

   
   printf("%8d%43s%19s%14d\n",nd->nd.iden,nd->nd.bookname,nd->nd.writer,nd->nd.price);

   nd=nd->next;
   
  }
 }
 

 //기본적으로 책식별자, 책이름, 저자, 가격)
 void BookInsert(List *list){

  char ask;
  //Node *node=(Node*)malloc(sizeof(Node));
  while(1){
  N_data data={0,NULL,NULL,0};
  printf("도서 식별번호를 입력:");
  scanf("%d",&data.iden);
  getchar();
  printf("도서 이름 입력:");
  gets(data.bookname);
  printf("도서 저자 이름 입력:");
  gets(data.writer);
  printf("도서 가격 입력:");
  scanf("%d",&data.price);
  getchar();

  if(list->comp==NULL)
   FBookInsert(list, data);

  else{
   SBookInsert(list,data);
  
  }
  printf("계속 입력하시겠습니까?(y or n):");
  scanf("%c",&ask);

  if(ask=='y')
   continue;
  else if(ask !='y' && ask !='n'){
   printf("\n");
   printf("잘못된 입력입니다.!\n");
   return;
  }
  else
   break;
 }

 }

 //첫번째 책정보를 입력하는 함수
 void FBookInsert(List *list, N_data data){
  
  Node *newnode =(Node*)malloc(sizeof(Node)); //새로운 노드 생성
  newnode->nd.iden=data.iden;
  newnode->nd.price=data.price;
  strcpy(newnode->nd.bookname,data.bookname);
  strcpy(newnode->nd.writer,data.writer); //데이터 입력

  newnode->next=list->head->next; //새로운 노드가 헤드가 가리키는 주소값을 저장하고 maybe NULL
  list->head->next=newnode; //헤드는 처음 시작하는 새로운 노드를 주소값으로 가진다.
 
 }
 //두번째 책정보를 입력하는 함수
 void SBookInsert(List *list,N_data data){

  Node *newnode=(Node*)malloc(sizeof(Node));
  Node *pred=list->head; //pred를 만들어서 head를 가르킨다. pred가 움직이면서 값을 비교하는데 사용되어진다.
  newnode->nd.iden=data.iden;
  newnode->nd.price=data.price;
  strcpy(newnode->nd.bookname,data.bookname);
  strcpy(newnode->nd.writer,data.writer); //데이터 입력

  while(pred->next != NULL && list->comp(data.iden, pred->next->nd.iden)  !=0)
  {
   if(data.iden==pred->next->nd.iden){
   printf("이미 중복되는 식별자입니다. 입력을 처음부터 다시해주세요\n");
   return;
   }
   pred = pred->next;
  }//새로 입력하는 함수.

  newnode->next=pred->next;
  pred->next=newnode;
 }

 //도서정보를 수정하는 함수
 void BookFix(List *list){

  int sbnum;
  int num;
  printf("수정하고자 하는 책의 식별번호를 입력해주세요:");
  scanf("%d",&sbnum);
 

  if( SearchBookFirst(list, &num)){
  
   if(num==sbnum){
   FixData(list);
   return;
   }
  }

  if( SearchBookFirst(list, &num)==0){
   printf("아직 데이터가 없습니다. .\n");
  
   return;
   }
  
  //두번 밖에 안되는 이유는 while문을 사용해주지 않아서 2개 이상으로는 확장이 되지 않는 것.
  while(SearchBookNext(list, &num)){
  
   if(num==sbnum){
   FixData(list);
   return;
   
  }
  }

  printf("찾으시고자 하는 데이터가 없습니다. 다시 확인해주시기 바랍니다.\n");
  return;
   
 }

 void BookDeletion(List *list){

  int sbnum;
  int num;
  printf("삭제하고자 하는 책의 식별번호를 입력해주세요:");
  scanf("%d",&sbnum);
 

  if( SearchBookFirst(list, &num)){
  
   if(num==sbnum){
   DeletionData(list);
   return;
   }
  }

  if( SearchBookFirst(list, &num)==0){
   printf("아직 데이터가 없습니다. .\n");
  
   return;
   }
  
  //두번 밖에 안되는 이유는 while문을 사용해주지 않아서 2개 이상으로는 확장이 되지 않는 것.
  while(SearchBookNext(list, &num)){
  
   if(num==sbnum){
   DeletionData(list);
   return;
   
  }
  }

  printf("찾으시고자 하는 데이터가 없습니다. 다시 확인해주시기 바랍니다.\n");
  return;

 }
 
 void ProgramClose(List *list){

  FILE *stream;
 
  Node *nd=list->head->next;
  stream=fopen("bookdata.txt","w");

  if(nd==NULL){
   return;
  }

  while(nd!=NULL){

  fprintf(stream,"%d %d\n%s\n%s\n",nd->nd.iden,nd->nd.price,nd->nd.bookname,nd->nd.writer);
   nd=nd->next;
  }

  fclose(stream);
 }


 int SearchBookFirst(List *list,int *num){

 if(list->head->next==NULL)
  return 0;

 list->before = list->head;
 list->cur = list->head->next;

 *num=list->cur->nd.iden;
  return 1;

}
 int SearchBookNext(List *list,int *num){

 if(list->cur->next==NULL)
  return 0;

 list->before=list->cur;
 list->cur=list->cur->next;

 *num=list->cur->nd.iden;
  return 1;
}
 //정렬을 위해 사용되어지는 함수
 void SetSortRule(List *list, int (*comp)(int iden1, int iden2)){
 
 list->comp=comp;

}

 int WhoIsPrecede(int iden1, int iden2){
  if(iden1 < iden2)
   return 0;

  else
   return 1;
 }

 //도서를 보여주기 위해 실제로 호출되는 함수
 void ShowData(List *list){

  Node *c_nd=list->cur;

    printf("식별번호 \t\t       도서 이름       \t\t    저자 이름   \t가격\n");
    printf("%8d%43s%19s%14d\n",c_nd->nd.iden,c_nd->nd.bookname,c_nd->nd.writer,c_nd->nd.price);
}
 //도서를 수정하기 위해 실제로 수정하는 함수
 void FixData(List *list){

  int chose_num;
  Node *c_nd=list->cur;

  Node *pred=list->head; //pred를 만들어서 head를 가르킨다. pred가 움직이면서 값을 비교하는데 사용되어진다.
  N_data nd;
 

  printf("무엇을 수정하시겠습니까?\n");
  while(1){
  printf("1)모두(도서,저자,가격) 2)도서 이름 3)저자 4)가격 5)취소:");
  scanf("%d",&chose_num);
  getchar();
  
  switch(chose_num){

  case 1:
  printf("도서 이름 입력:");
  gets(nd.bookname);
  strcpy(c_nd->nd.bookname,nd.bookname);
  printf("도서 저자 이름 입력:");
  gets(nd.writer);
  strcpy(c_nd->nd.writer,nd.writer);
  printf("도서 가격 입력:");
  scanf("%d",&nd.price);
  c_nd->nd.price=nd.price;
 
   return;

  case 2:
     printf("도서 이름 입력:");
  gets(nd.bookname);
  strcpy(c_nd->nd.bookname,nd.bookname);
   return;

  case 3:
  printf("도서 저자 이름 입력:");
  gets(nd.writer);
  strcpy(c_nd->nd.writer,nd.writer);
   return;

  case 4:
  printf("도서 가격 입력:");
  scanf("%d",&nd.price);
  c_nd->nd.price=nd.price;
   return;
  case 5:
   return;

  default:
   printf("잘못 입력하였습니다.");
   continue;

  }
  }
 }
 //도서를 삭제하기 위해 실제로 삭제하는 함수
 void DeletionData(List *list){

   Node *c_nd=list->cur;
  
   list->before->next =list->cur->next;
   list->cur = list->before;

   free(c_nd);

   printf("성공적으로 삭제가 되었습니다!!\n");
 
 }