C언어 장르별 도서관리 프로그램 소스코드

이번에 올리는 코드는 C언어 장르별 도서관리 프로그램 소스코드 입니다.

앞에서 올린 도서관리 프로그램 예관탄에서 각각의 함수의 기능들을 추가해서 

함수 내부의 코드들을 완성시켰고 또한 거기에 도서 장르를 추가해 장르별 도서관리 프로그램을 완성시켰습니다.


연습하는겸 해서 한번씩 따라 쳐 보시면 프로그램의 흐름을 이해하기 쉬울겁니다.^^

===================================================================

//App.h

#pragma once

void Start_App();

===================================================================


//App.c

#include "Genre.h"

#include "EHArr.h"

#include "App.h"

#include "ehcommon.h"

#include "Book.h"

typedef struct App App;


struct App

{

EHArr *genres;

//EHArr *books;

int last_gnum; //장르 일련번호 결정

};


App *New_App(); //App 동적할당

void Delete_App(App *app); //App 동적할당 해제

void App_Init(App *app); //App 내용 초기화

void App_Run(App *app); //App 실행

void App_Exit(App *app); //App 해제화

void App_Save(App *app); //App 저장함수

void App_Serialize(App *app, FILE *fp); //App 직렬화


void Start_App()

{

App *app = New_App();

App_Init(app);

App_Run(app);

App_Exit(app);

Delete_App(app);

}

///////////////////////////////////////////////

App *New_App() //App 동적할당

{

App *app = (App *)malloc(sizeof(App));

return app;

}


void Delete_App(App *app) //App 동적할당 해제

{

free(app);

}


void App_Init(App *app) //App 내용 초기화

{

app->genres = New_EHArr();

app->last_gnum = 0; //장르번호 초기화

}


int App_SelectMenu(App *app);//메뉴바

void App_AddGenre(App *app); //장르 추가 

void App_RemoveGenre(App *app); //장르 삭제

void App_ListGenre(App *app); //전체장르 보기

void App_ViewGenre(App *app); //특정 장르의 도서목록 보기

void App_AddBook(App *app); //도서추가 

void App_SearchByBNum(App *app); //도서 일력번호로 검색

void App_SearchByName(App *app); //도서 이름으로 검색

void App_ListAll(App *app); //전체도서보기

void GenreBookAllView(Genre *genre); //장르에 있는 도서들 보여주는 함수


void App_Run(App *app)

{

int key = 0;

while((key = App_SelectMenu(app)) != ESC)

{

switch(key)

{

case F1: App_AddGenre(app); break;

case F2: App_RemoveGenre(app); break;

case F3: App_ListGenre(app); break;

case F4: App_ViewGenre(app); break;

case F5:App_AddBook(app);break;

case F6: App_SearchByBNum(app); break;

case F7: App_SearchByName(app); break;

case F8: App_ListAll(app); break;

default: printf("잘못 선택하였습니다.\n"); break;

}

printf("아무 키나 누르세요.\n");

getkey();

}

}

void App_Exit(App *app) //해제화

{

Iterator seek = 0;

Iterator last = 0;

Genre *genre = 0;


seek = EHArr_Begin(app->genres);

last = EHArr_End(app->genres);


for(  ; seek != last; seek++)

{

genre = (Genre*)(*seek);

Delete_Genre(genre);

}

Delete_EHArr(app->genres); //생성한 부분은 바로 소멸해라.

}


////////////////////////////////////////////////////////////////////

int App_SelectMenu(App *app) //메뉴바

{

clrscr();

printf("\t\t<<프로그램 상호 작용 - 메뉴>>\n\n");

printf("\t\tF1: 장르 추가\n\t\tF2:장르삭제\n\t\tF3:전체장르보기\n\t\tF4:특정장르의도서목록보기\n\t\tF5:도서추가\n\t\tF6:도서일련번호로검색\n\t\tF7:도서이름으로검색\n\t\tF8:전체도서보기\n\n");

printf("\t\t<<ESC를 누르면 프로그램을 종료합니다.>>\n");

printf("\t\t<<메뉴를 선택하세요.>>\n\n");

return getkey();

}

Genre *App_FindGenre(App *app, const char *gname);//장르 이름 검색비교

Iterator App_FindSeek(App *app, const char *gname);//seek주소를 반환해주는 함수


void App_AddGenre(App *app) //장르 추가

{

char gname[MAX_GNLEN] = "";

Genre *genre = 0;


printf("%d번째 생성할 장르 이름 : ",app->last_gnum+1);

scanf_s("%s",gname,MAX_GNLEN);


genre = App_FindGenre(app,gname);


if(genre)

{

printf("이미 존재하는 장르입니다.\n");

return;

}

genre = New_Genre(app->last_gnum+1,gname);

app->last_gnum++;

EHArr_PushBack(app->genres,genre);

printf("장르가 추가되었습니다.\n");

}


Genre *App_FindGenre(App *app, const char *gname) //장르 이름 검색비교

{

Iterator seek = 0;

Iterator last = 0;

Genre *genre = 0;

const char *ogname = 0;


seek = EHArr_Begin(app->genres);

last = EHArr_End(app->genres);


for(  ; seek != last; seek++)

{

genre = (Genre*)(*seek);

ogname = Genre_GetName(genre);


if(strcmp(gname, ogname) == 0)

{

return genre;

}

}

return 0;

}


Iterator App_FindSeek(App *app, const char *gname) //seek주소를 반환해주는 함수

{

Iterator seek = 0;

Iterator last = 0;

Genre *genre = 0;

const char *ogname = 0;


seek = EHArr_Begin(app->genres);

last = EHArr_End(app->genres);


for(  ; seek != last; seek++)

{

genre = (Genre*)(*seek);

ogname = Genre_GetName(genre);


if(strcmp(ogname,gname) == 0)

{

break;

}

}

return seek;

}


void App_RemoveGenre(App *app) //장르 삭제

{

char gname[MAX_GNLEN] = "";

Iterator  seek = 0;

Iterator last = 0;


Genre *genre = 0;


last = EHArr_End(app->genres);


App_ListGenre(app);

printf("삭제할 장르를 입력해 주세요:\n");

scanf_s("%s",gname,MAX_GNLEN);


seek = App_FindSeek(app,gname);


if(seek == last)

{

printf("입력하신 장르는 없는 장르입니다.\n");

return;

}


genre = (Genre*)(*seek);

Delete_Genre(genre);

EHArr_Erase(app->genres,seek);

printf("%s 장르가 삭제되었습니다.\n",gname);

}


void App_ListGenre(App *app) //전체 장르 보기

{

Iterator  seek = 0;

Iterator  last = 0;

Genre *genre = 0;


seek = EHArr_Begin(app->genres);

last = EHArr_End(app->genres);


for(  ; seek != last; seek++)

{

genre = (Genre*)(*seek);

Genre_View(genre);

}

}


void App_ViewGenre(App *app) //특정 장르의 도서 목록 보기

{

char gname[MAX_GNLEN] = "";

Iterator seek = 0;

Iterator last = 0;


Genre *genre = 0;

seek = EHArr_Begin(app->genres);

last = EHArr_End(app->genres);


App_ListGenre(app);

printf("어떤 장르의 정보를 보고 싶으신가요 ?\n");

scanf_s("%s",gname,MAX_GNLEN);


seek = App_FindSeek(app,gname);

genre = App_FindGenre(app,gname);


if(seek == last)

{

printf("입력하신 장르의 정보는 없는 장르입니다.\n");

return;

}

genre = (Genre*)(*seek);

GenreBookAllView(genre);

}


void App_AddBook(App *app) //도서 추가

{

char gname[MAX_GNLEN] = ""; //장르명

char title[MAX_TLEN] = ""; //도서명

char author[MAX_TLEN] = ""; //도서저자


Genre *genre = 0;


Iterator seek = 0;

Iterator last = 0;


last = EHArr_End(app->genres);


App_ListGenre(app);

printf("어떤 장르에 도서를 추가하시겠습니까?\n");

scanf_s("%s",gname,MAX_GNLEN);


seek = App_FindSeek(app,gname);

genre = App_FindGenre(app,gname);


if(seek == last)

{

printf("입력하신 장르가 존재하지 않습니다.\n");

return;

}


printf("추가할 도서명을 입력하세요 :\n");

scanf_s("%s",title,MAX_TLEN);

printf("추가할 도서명의 저자를 입력하세요 :\n");

scanf_s("%s",author,MAX_TLEN);


Genre_AddBook(genre,title,author); //장르에 도서를 추가해서 넣어주는 함수

}


void App_SearchByBNum(App *app) //도서 일련 번호로 검색

{

char gname[MAX_GNLEN] = "";

int bnum = 0;


Iterator seek = 0;

Iterator last = 0;


Genre *genre = 0;

Book *book = 0;


last = EHArr_End(app->genres);


App_ListGenre(app);

printf("어떤 장르의 도서를 찾고 싶으신가요?\n");

scanf_s("%s",gname,MAX_GNLEN);


seek = App_FindSeek(app,gname);

genre = App_FindGenre(app,gname);


if(seek == last)

{

printf("찾으시는 장르는 없는 장르입니다.\n");

return;

}


printf("찾으시는 도서번호를 입력하세요 :\n");

scanf_s("%d",&bnum);


book = App_FindBookNumSeek(genre,bnum);


if(book == 0)

{

printf("입력하신 번호의 도서는 없는 도서입니다.\n");

}

else

{

Book_View(book);

}

}


void App_SearchByName(App *app) //도서 이름으로 검색

{

char gname[MAX_GNLEN] = "";

char bname[MAX_TLEN] = "";

Iterator seek = 0;

Iterator last = 0;


Genre *genre = 0;

Book *book = 0;


last = EHArr_End(app->genres);


App_ListGenre(app);

printf("어떤 장르의 도서를 찾으시나요? \n");

scanf_s("%s",gname,MAX_GNLEN);


seek = App_FindSeek(app,gname);

genre = App_FindGenre(app,gname);


if(seek == last)

{

printf("찾으시는 장르는 없는 장르입니다.\n");

return;

}


printf("찾으시는 책의 이름을 입력해 주세요:\n");

scanf_s("%s",bname,MAX_TLEN);


book = App_FindBookNameSeek(genre,bname);


if(book == 0)

{

printf("입력하신 도서명의 도서는 없는 도서입니다.\n");

}

else

{

Book_View(book);

}

}


void App_ListAll(App *app) //전체 도서 보기

{

Iterator seek = 0;

Iterator last = 0;


Genre *genre = 0;


seek = EHArr_Begin(app->genres);

last = EHArr_End(app->genres);


App_ListGenre(app);

printf("\n");


for(  ; seek != last; seek++)

{

genre = (Genre*)(*seek);

GenreBookAllView(genre);

}

}

===================================================================

//Book.h

#pragma once //헤더 파일을 여러번 include 해도 오류 안 생기게 한다.

#define MAX_TLEN 200 


typedef struct Book Book;


struct Book

{

int bnum;

char title[MAX_TLEN];

char author[MAX_TLEN];

};


Book *New_Book(int bnum, const char *title, const char *author); //도서 동적할당

void Delete_Book(Book *book); //도서 동적할당 해제

int Book_GetBNum(Book *book) ;//도서 일련번호 접근 지정자

const char *Book_GetTitle(Book *book); //도서명 접근 지정자

void Book_View(Book *book); //도서정보 출력


===================================================================

//Book.c

#include "Book.h"

#include "ehcommon.h"


void Book_Book(Book *book, int bnum, const char *title,const char *author); //생성자


Book *New_Book(int bnum, const char *title, const char *author) //동적 할당

{

Book *book = 0;

book = (Book*)malloc(sizeof(Book));

Book_Book(book,bnum,title,author);

return book;

}

void Delete_Book(Book *book) //동적 할당 해제

{

free(book);

}


int Book_GetBNum(Book *book) //책 번호 접근 지정자

{

return book->bnum;

}


const char *Book_GetTitle(Book *book) //도서명 접근 지정자

{

return book->title;

}


void Book_View(Book *book) //책 정보 출력

{

printf("\t\t도서번호 : %03d 도서명 : %s 도서저자 : %s\n", book->bnum,book->title,book->author);

}


void Book_Book(Book *book, int bnum, const char *title, const char *author) //생성자

{

book->bnum = bnum;

strcpy_s(book->title,MAX_TLEN,title);

strcpy_s(book->author,MAX_TLEN,author);

}


void Book_Serialzie(Book *book, FILE *fp)

{

fwrite(book,sizeof(Book),1,fp);

}

===================================================================

//EHArr.h

#pragma once


typedef void * Element;

typedef Element * Iterator;

typedef struct EHArr EHArr;

struct EHArr

{

    Element *base; //저장소 위치

    int capacity; //저장소의 용량

    int size; //보관 개수

};


EHArr *New_EHArr();

void Delete_EHArr(EHArr *eharr);


void EHArr_PushBack(EHArr *eharr, Element data);//순차 보관

Iterator EHArr_Begin(EHArr *eharr);//시작 위치 반환

Iterator EHArr_End(EHArr *eharr);//마지막(+1) 위치 반환

void EHArr_Erase(EHArr *eharr, Iterator iter);//iter 위치 요소 지우기


void EHArr_Reserve(EHArr *eharr,int newcapa);

void EHArr_Resize(EHArr *eharr, int newsize, Element data);

Element EHArr_GetAt(EHArr *eharr,int index);//특정 인덱스에 보관한 데이터 접근

void EHArr_SetAt(EHArr *eharr,int index,Element data);//특정 인덱스에 데이터 설정


===================================================================

//EHArr.c

#include "ehcommon.h"

#include "EHArr.h"

void EHArr_EHArr(EHArr *eharr);

EHArr *New_EHArr()

{

    EHArr *eharr = (EHArr *)malloc(sizeof(EHArr));

    EHArr_EHArr(eharr);

    return eharr;

}

void EHArr_EHArr(EHArr *eharr)

{

    memset(eharr,0,sizeof(EHArr));

}

void EHArr_TEHArr(EHArr *eharr);//소멸자

void Delete_EHArr(EHArr *eharr)

{

    EHArr_TEHArr(eharr);

    free(eharr);

}

void EHArr_TEHArr(EHArr *eharr)

{

    if(eharr->base)

    {

        free(eharr->base);

    }

}

void EHArr_PushBack(EHArr *eharr, Element data)

{

    if(eharr->capacity == eharr->size)//꽉 찼으면

    {

        //공간 재할당

        if(eharr->capacity)

        {

            EHArr_Reserve(eharr,eharr->capacity*2);

        }

        else

        {

            EHArr_Reserve(eharr,1);

        }

    }

    eharr->base[eharr->size] = data;//맨 뒤에 data 보관

    eharr->size++;//보관 개수 1 증가

}

Iterator EHArr_Begin(EHArr *eharr)

{

    return eharr->base;

}

Iterator EHArr_End(EHArr *eharr)

{

    return eharr->base + eharr->size;

}

void EHArr_Erase(EHArr *eharr, Iterator iter)

{

    int index;

    eharr->size--;

    for(index = iter-eharr->base; index<eharr->size; index++)

    {

        eharr->base[index] = eharr->base[index+1];

    }

}


void EHArr_Reserve(EHArr *eharr,int newcapa)

{

    eharr->base = (Element *)realloc(eharr->base,sizeof(Element)*newcapa);

    eharr->capacity = newcapa;

}

void EHArr_Resize(EHArr *eharr, int newsize, Element data)

{

    if(eharr->capacity < newsize)

    {

        EHArr_Reserve(eharr,newsize);

    }

    for(   ;eharr->size < newsize; ++eharr->size)

    {

        eharr->base[eharr->size] = data;

    }

}

Element EHArr_GetAt(EHArr *eharr,int index)

{

    if((index>=0)&&(index<eharr->size))

    {

        return eharr->base[index];

    }    

    return 0;

}

void EHArr_SetAt(EHArr *eharr,int index,Element data)

{

    if((index>=0)&&(index<eharr->size))

    {

        eharr->base[index] = data;

    }

}


===================================================================

//ehcommon.h

#pragma once

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <math.h>

#include <time.h>

#include <assert.h>

#include <ctype.h>


#include <conio.h> //표준 라이브러리 헤더가 아님

enum ehkey

{

    NO_KEY, F1, F2, F3, F4, F5, F6, F7, F8, F9, ESC

};

int getkey();

void clrscr();


===================================================================

//ehcommon.c

#pragma warning(disable:4996)

#include "ehcommon.h"

int getkey()

{

    int key = 0;

    key = getch();

    if(key == 27)

    {

        return ESC;

    }

    if(key == 0)

    {

        key = getch();

        switch(key)

        {

        case 59: return F1;

        case 60: return F2;

        case 61: return F3;

        case 62: return F4;

        case 63: return F5;

        case 64: return F6;

        case 65: return F7;

        case 66: return F8;

        case 67: return F9;            

        }

    }

    return NO_KEY;

}

void clrscr()

{

    system("cls");

}


===================================================================

//Genre.h

#pragma once


#include "Book.h"

#include "EHArr.h"


#define MAX_GNLEN 200


typedef struct Genre Genre;



struct Genre

{

EHArr *books; //책을 보관하기 위한 배열 멤버

int num; //장르번호

char name[MAX_GNLEN]; //장르 이름

int last_bnum; //도서 일련번호 결정

};


Genre *New_Genre(int num, const char *name);//동적 할당

void Delete_Genre(Genre *genre);//동적할당 해제

const char *Genre_GetName(Genre *genre);//문자열 반환

void Genre_View(Genre *genre); //장르 정보 출력

void Genre_AddBook(Genre *genre,const char *title, const char *author); //도서를 추가해 장르에다 도서를 넣어줌

Book *App_FindBookNumSeek(Genre *genre, int bnum);//Book을 반환해주는 함수

Book *App_FindBookNameSeek(Genre *genre, const char* bname);//Book을 반환해주는 함수

void GenreBookAllView(Genre *genre);//장르 안에있는 도서들 보여주는 함수


===================================================================

//Genre.c

#include "Genre.h"

#include "ehcommon.h"

#include "EHArr.h"


void Genre_Genre(Genre *genre, int num , const char *name);

void Genre_TGenre(Genre *genre);


Genre *New_Genre(int num, const char *name) //장르 동적할당 함수

{

Genre *genre = (Genre*)malloc(sizeof(Genre));

Genre_Genre(genre,num,name);

return genre;

}


void Genre_Genre(Genre *genre, int num , const char *name) //장르 생성자

{

genre->last_bnum = 0;

genre->num = num;

strcpy_s(genre->name,MAX_GNLEN,name);

genre->books = New_EHArr();

}


void Delete_Genre(Genre *genre) //장르 동적할당 해제

{

Genre_TGenre(genre);

free(genre);

}


void Genre_TGenre(Genre *genre) //장르 소멸자

{

Delete_EHArr(genre->books);

}


const char *Genre_GetName(Genre *genre) //장르이름 반환

{

return genre->name;

}


void Genre_View(Genre *genre) //장르정보 출력

{

printf("\t\t장르 번호 : %03d 장르명 : %s\t\n",genre->num,genre->name);

}


void Genre_AddBook(Genre *genre,const char *title, const char *author) //장르에 도서를 추가해서 넣어주는 함수

{

Book *book = 0;

genre->last_bnum++;

book = New_Book(genre->last_bnum,title,author);

EHArr_PushBack(genre->books,book);

printf("도서가 장르에 성공적으로 추가 되었습니다.\n");

}


Book *App_FindBookNumSeek(Genre *genre, int bnum) //도서 일련번호로 검색해서 도서를 반환해주는 함수

{

Iterator seek = 0;

Iterator last = 0;


Book *book = 0;


seek = EHArr_Begin(genre->books);

last = EHArr_End(genre->books);


Genre_View(genre);

for(  ; seek != last; seek++)

{

book = (Book*)(*seek);

if(Book_GetBNum(book) == bnum)

{

return book;

}

}

return 0;

}

Book *App_FindBookNameSeek(Genre *genre, const char* bname) //도서 이름을 검색해서 도서를 반환해주는 함수

{

Iterator seek = 0;

Iterator last = 0;

const char *obname = 0;


Book *book = 0;


seek = EHArr_Begin(genre->books);

last = EHArr_End(genre->books);


Genre_View(genre);

for(  ; seek != last; seek++)

{

book = (Book*)(*seek);

obname = Book_GetTitle(book);


if(strcmp(bname,obname) == 0)

{

return book;

}

}

return 0;

}

void GenreBookAllView(Genre *genre)//장르 안에있는 도서들 보여주는 함수

{

Iterator seek = 0;

Iterator last = 0;

Book *book = 0;


seek = EHArr_Begin(genre->books);

last = EHArr_End(genre->books);


if(seek == last)

{

printf("도서가 없습니다.\n");

return;

}


Genre_View(genre);

for(  ; seek != last; seek++)

{

book = (Book*)(*seek);

Book_View(book);

}

printf("\n");

}


===================================================================

//Program.c

#include "App.h"

int main()

{

    Start_App();

    return 0;

}


728x90

이 글을 공유하기

댓글

Designed by JB FACTORY