#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");
}