언어 자료구조 알고리즘/디딤돌 C언어

[c language] 101~114 도서 관리 프로그램 소스 코드

언제나휴일 2016. 4. 24. 17:35
반응형


도서 관리 프로그램.zip


도서 관리 프로그램 소스 코드


다음은 이번 실습에서 작성한 도서 관리 프로그램의 소스 코드입니다.

// ehcommon.h

#pragma once

typedef enum _key key;

enum _key

{

    NO_DEFINED, F1, F2, F3, F4, F5, F6, F7, F8, F9,F10, ESC

};

void clrscr();

int getkey();

 

//ehcommon.c

#pragma warning(disable:4996)

#include "ehcommon.h"

#include <conio.h>

#include <stdio.h>

#include <process.h>

void clrscr()

{

    system("cls");

}

 

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; case 68: return F10;

        }

    }

    return NO_DEFINED;

 

// EHArray.h

#pragma once

typedef struct _EHArray EHArray;

typedef void *Element; //요소 형식명을 Element로 정의

typedef Element * Iterator;

struct _EHArray

{

    Element *base; //저장소의 위치 정보

    int capacity;     //현재 저장소의 크기

    int size;           //현재 보관한 요소 개수

};

 

EHArray *NewEHArray(int init_capa,Element init_value); //동적으로 배열 생성

void DeleteEHArray(EHArray *arr); //배열 소멸

int EHArrayGetCapacity(EHArray *arr); //저장소의 크기 가져오기

int EHArrayGetSize(EHArray *arr);       //보관한 요소 개수 가져오기

void EHArrayPushBack(EHArray *arr,Element data); //순차적으로 자료 보관

Element EHArrayGetAt(EHArray *arr,int index); //보관한 요소 가져오기

void EHArraySetAt(EHArray *arr,int index, Element data); //보관한 요소 설정하기

Iterator EHArrayBegin(EHArray *arr); //저장소의 시작 위치

Iterator EHArrayEnd(EHArray *arr); //저장소의 마지막 위치(보관할 위치)

void EHArrayErase(EHArray *arr,Iterator it);//보관한 요소 제거하기

 

#include "EHArray.h"

#include <stdlib.h>

 

void EHArrayEHArray(EHArray *arr,int init_capa,Element init_value);

void EHArrayReserve(EHArray *arr,int capacity);

void EHArrayPushBacks(EHArray *arr,int n,Element value);

void EHArrayTEHArray(EHArray *arr);

 

EHArray *NewEHArray(int init_capa,Element init_value)

{

    EHArray *arr = (EHArray *)malloc(sizeof(EHArray));

    EHArrayEHArray(arr,init_capa,init_value);

    return arr;

 

void EHArrayEHArray(EHArray *arr,int init_capa,Element init_value)

{

    arr->base = 0;

    arr->capacity = 0;

    arr->size = 0;

    if(init_capa>0)

    {

        EHArrayReserve(arr,init_capa);

        EHArrayPushBacks(arr,init_capa,init_value);

    }

}

void EHArrayReserve(EHArray *arr,int capacity)

{

    arr->base = (Element *)realloc(arr->base,sizeof(Element)*capacity);

    arr->capacity = capacity;

}

void EHArrayPushBacks(EHArray *arr,int n,Element value)

{

    int i = 0;

    for(i=0;i<n;i++)

    {

        EHArrayPushBack(arr,value);

    }

}

void DeleteEHArray(EHArray *arr)

{

    EHArrayTEHArray(arr);

    free(arr);

 

void EHArrayTEHArray(EHArray *arr)

{

    if(arr->base)

    {

        free(arr->base);

    }

}

int EHArrayGetCapacity(EHArray *arr)

{

    return arr->capacity;

}

int EHArrayGetSize(EHArray *arr)

{

    return arr->size;

}

 

 

void EHArrayPushBack(EHArray *arr,Element data)

{

    if(arr->capacity == arr->size)

    {

        if(arr->capacity)

        {

            EHArrayReserve(arr,arr->capacity*2);

        }

        else

        {

            EHArrayReserve(arr,1);

        }

    }

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

    arr->size++;

}

Element EHArrayGetAt(EHArray *arr,int index)

{

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

    {

        return arr->base[index];

    }

    return 0;

}

void EHArraySetAt(EHArray *arr,int index, Element data)

{

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

    {

        arr->base[index] = data;

    }

}

Iterator EHArrayBegin(EHArray *arr)

{

    return arr->base;  

}

Iterator EHArrayEnd(EHArray *arr)

{

    return arr->base + arr->size;

}

void EHArrayErase(EHArray *arr,Iterator it)

{

    Iterator end;

    arr->size--;

    end = arr->base + arr->size;

    for(  ; it != end; it++)

    {

        (*it) = *(it+1);

    }

}

 

 

// Book.h

#pragma once

#include <stdio.h>

typedef struct _Book Book;

#define MAX_TNAME_LEN     100

#define MAX_ANAME_LEN 20

struct _Book

{

    char title[MAX_TNAME_LEN+1];

    char author[MAX_ANAME_LEN+1];

    int bnum;

};

Book *NewBook(int bnum,const char *title,const char *author);

Book *NewBook2(FILE *fp);

void DeleteBook(Book *book);

void BookView(Book *book);

int BookGetNum(Book *book);

const char *BookGetTitle(Book *book);

void BookSerialize(Book *book,FILE *fp);

 

//Book.c

#pragma warning(disable:4996)

#include "Book.h"

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

void BookBook(Book *book,int bnum,const char *title,const char *author);

Book *NewBook(int bnum,const char *title,const char *author)

{

    Book *book = 0;

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

    BookBook(book,bnum,title,author);

    return book;

}

void BookDeserialize(Book *book,FILE *fp);

Book *NewBook2(FILE *fp)

{

    Book *book = 0;

    book = NewBook(0,"","");

    BookDeserialize(book,fp);

    return book;

}

void BookDeserialize(Book *book,FILE *fp)

{

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

}

 

 

void BookBook(Book *book,int bnum,const char *title,const char *author)

{

    book->bnum = bnum;

    memset(book->title,0,sizeof(book->title));

    strncpy(book->title,title,MAX_TNAME_LEN);

    memset(book->author,0,sizeof(book->author));

    strncpy(book->author,author,MAX_ANAME_LEN);

}

void DeleteBook(Book *book)

{

    free(book);

}

void BookView(Book *book)

{

    printf("제목:%s\n",book->title);

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

}

int BookGetNum(Book *book)

{

    return book->bnum;

}

 

const char *BookGetTitle(Book *book)

{

    return book->title;

}

void BookSerialize(Book *book,FILE *fp)

{

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

}

 

// Gerne.h

#pragma once

#include "Book.h"

#include "EHArray.h"

typedef struct _Genre Genre;

#define MAX_GNAME_LEN 20

struct _Genre

{

    char name[MAX_GNAME_LEN+1];

    int gnum;

    int last_bnum;

    EHArray *books;

};

Genre *NewGenre(int gnum,const char *gname);

Genre *NewGenre2(FILE *fp);

void DeleteGenre(Genre *genre);

const char *GenreGetName(Genre *genre);

void GenreView(Genre *genre);

void GenreAddBook(Genre *genre,const char *title,const char *author);

void GenreViewAll(Genre *genre);

Book *GenreFindBookByNum(Genre *genre,int bnum);

Book *GenreFindBookByTitle(Genre *genre,const char *title);

void GenreSerialize(Genre *genre,FILE *fp);

 

//Genre.c

#pragma warning(disable:4996)

#include "Genre.h"

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

 

void GenreGenre(Genre *genre,int gnum,const char *gname);

Genre *NewGenre(int gnum,const char *gname)

{

    Genre *genre = 0;

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

    GenreGenre(genre,gnum,gname);

    return genre;

}

void GenreGenre(Genre *genre,int gnum,const char *gname)

{

    genre->gnum = gnum;

    memset(genre->name,0,sizeof(genre->name));

    strncpy(genre->name,gname,MAX_GNAME_LEN);

    genre->books = NewEHArray(0,0);

    genre->last_bnum = 0;

}

void GenreDeserialize(Genre *genre,FILE *fp);

Genre *NewGenre2(FILE *fp)

{

    Genre *genre = 0;

    genre = NewGenre(0,"");

    GenreDeserialize(genre,fp);

    return genre;

}

void GenreDeserialize(Genre *genre,FILE *fp)

{

    Book *book=0;

    int i = 0;

    int n = 0;

    fread(genre->name,sizeof(genre->name),1,fp);

    fread(&(genre->gnum),sizeof(int),1,fp);

    fread(&(genre->last_bnum),sizeof(int),1,fp);

    fread(&n,sizeof(int),1,fp);

    for(i=0  ;i<n; i++)

    {

        book = NewBook2(fp);

        EHArrayPushBack(genre->books,book);

    }

}

 

void GenreTGenre(Genre *genre);

void DeleteGenre(Genre *genre)

{

    GenreTGenre(genre);

    free(genre);

}

void GenreTGenre(Genre *genre)

{

    Book *book=0;

    Iterator seek= EHArrayBegin(genre->books);

    Iterator end= EHArrayEnd(genre->books);

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

    {

        book = (Book *)(*seek);

        DeleteBook(book);

    }

    DeleteEHArray(genre->books);

}

 

int GenreGetNum(Genre *genre)

{

    return genre->gnum;

}

 

const char *GenreGetName(Genre *genre)

{

    return genre->name;

}

void GenreView(Genre *genre)

{

    printf("장르 번호:%d 장르 이름:%s\n",genre->gnum,genre->name);

}

 

void GenreAddBook(Genre *genre,const char *title,const char *author)

{

    Book *book = 0;

    genre->last_bnum++;

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

    EHArrayPushBack(genre->books,book);

    printf("도서번호:%d 로 추가하였습니다.\n",genre->last_bnum);

}

void GenreViewAll(Genre *genre)

{

    Iterator seek= EHArrayBegin(genre->books);

    Iterator end= EHArrayEnd(genre->books);

    Book *sbook=0;

    GenreView(genre);

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

    {

        sbook = (Book *)(*seek);

        BookView(sbook);

    }

}

 

Book *GenreFindBookByNum(Genre *genre,int bnum)

{

    Iterator seek;

    Iterator end;

    Book *book=0;

 

    seek= EHArrayBegin(genre->books);

    end= EHArrayEnd(genre->books);

 

    GenreView(genre);

 

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

    {

        book = (Book *)(*seek);

 

        if(BookGetNum(book) == bnum)

        {

            return book;

        }

    }

 

    return 0;

}

Book *GenreFindBookByTitle(Genre *genre,const char *title)

{

    Iterator seek;

    Iterator end;

    Book *book=0;

    const char *stitle = 0;

 

    seek= EHArrayBegin(genre->books);

    end= EHArrayEnd(genre->books);

 

    GenreView(genre);

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

    {

        book = (Book *)(*seek);

        stitle = BookGetTitle(book);

        if(strcmp(stitle,title)==0)

        {

            return book;

        }

    }

    return 0;

}

void GenreSerialize(Genre *genre,FILE *fp)

{

    Iterator seek;

    Iterator end;

    Book *book=0;

    int n = 0;

 

    fwrite(genre->name,sizeof(genre->name),1,fp);

    fwrite(&(genre->gnum),sizeof(int),1,fp);

    fwrite(&(genre->last_bnum),sizeof(int),1,fp);

 

    n = EHArrayGetSize(genre->books);

    fwrite(&n,sizeof(int),1,fp);

    seek= EHArrayBegin(genre->books);

    end= EHArrayEnd(genre->books);

 

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

    {

        book = (Book *)(*seek);

        BookSerialize(book,fp);

    }

}

 

//App.h

#pragma once

typedef struct _App    App;

#include "Genre.h"

#include "EHArray.h"

#include <stdio.h>

struct _App

{

    char fname[FILENAME_MAX];

    int last_gnum;

    EHArray *genres;

};

 

App *NewApp(const char *fname);

void AppRun(App *app);

void DeleteApp(App *app);

 

//App.c

#pragma warning(disable:4996)

#include "App.h"

#include "ehcommon.h"

#include <malloc.h>

#include <stdio.h>

#include <memory.h>

#include <string.h>

 

void AppApp(App *app,const char *fname);

void AppTApp(App *app);

void AppLoad(App *app);

void AppSave(App *app);

 

int AppSelectMenu(App *app);

void AppAddGenre(App *app);

void AppRemoveGenre(App *app);

void AppListGenre(App *app);

void AppListBookAtGenre(App *app);

void AppAddBook(App *app);

void AppFindBookByNum(App *app);

void AppFindBookByTitle(App *app);

void AppListAll(App *app);

 

App *NewApp(const char *fname)

{

    App *app = 0;

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

    AppApp(app,fname);

    return app;

}

 

void AppApp(App *app,const char *fname)

{

    memset(app->fname,0,sizeof(app->fname));

    strncpy(app->fname,fname,FILENAME_MAX);

    app->genres = NewEHArray(0,0);

    app->last_gnum = 0;

    AppLoad(app);

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

    getkey();

}

 

void AppDeserialize(App *app,FILE *fp);

void AppLoad(App *app)

{

    FILE *fp = 0;

    fp = fopen(app->fname,"r");

    if(fp)

    {

        AppDeserialize(app,fp);

    }

    else

    {

        printf("환영합니다.\n");

    }

}

void AppDeserialize(App *app,FILE *fp)

{

    int n = 0;

    int i = 0;

    Genre *genre=0;

    fread(&(app->last_gnum),sizeof(int),1,fp);

    fread(&n,sizeof(int),1,fp);

    for( i=0 ;i<n;i++)

    {

        genre = NewGenre2(fp);

        EHArrayPushBack(app->genres,genre);

    }

}

 

 

 

 

void AppRun(App *app)

{

    int key = 0;

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

    {

        switch(key)

        {

        case F1: AppAddGenre(app); break;

        case F2: AppRemoveGenre(app); break;

        case F3: AppListGenre(app); break;

        case F4: AppListBookAtGenre(app); break;

        case F5: AppAddBook(app); break;

        case F6: AppFindBookByNum(app); break;

        case F7: AppFindBookByTitle(app); break;

        case F8: AppListAll(app); break;

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

        }

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

        getkey();

    }

}

int AppSelectMenu(App *app)

{

    clrscr();

    printf("장르별 도서관리 프로그램 \n");

    printf("F1:장르 추가 F2: 장르 삭제 F3: 전체 장르 보기\n");

    printf("F4: 특정 장르의 도서 목록 보기\n");

    printf("F5:도서 추가 F6: 도서 검색(일련번호) F7: 도서검색(제목)\n");

    printf("F8: 전체 도서 보기 ESC: 종료\n");

    return getkey();

}

 

Iterator AppFindGenre(App *app,const char *gname);

void AppAddGenre(App *app)

{

    char gname[MAX_GNAME_LEN+1]="";

    Iterator seek = 0;

    Genre *genre = 0;

 

    printf("%d번째 추가할 장르명을 입력하세요.\n",app->last_gnum+1);

    gets_s(gname,MAX_GNAME_LEN);

 

    seek = AppFindGenre(app,gname);

    if(seek != EHArrayEnd(app->genres))

    {

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

        return;

    }

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

    app->last_gnum++;

    EHArrayPushBack(app->genres,genre);

}

Iterator AppFindGenre(App *app,const char *gname)

{

    Iterator seek;

    Iterator end;

    Genre *sgenre=0;

    const char *sgname=0;

 

    seek = EHArrayBegin(app->genres);

    end = EHArrayEnd(app->genres);

 

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

    {

        sgenre = (Genre *)(*seek);

        sgname = GenreGetName(sgenre);

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

        {

            break;

        }

    }

    return seek;

}

 

void AppRemoveGenre(App *app)

{

    char gname[MAX_GNAME_LEN+1]="";

    Iterator seek = 0;

    Genre *genre = 0;

    AppListGenre(app);

    printf("삭제할 장르명을 입력하세요.\n");

    gets_s(gname,MAX_GNAME_LEN);

    seek = AppFindGenre(app,gname);

    if(seek == EHArrayEnd(app->genres))

    {

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

        return;

    }

    genre = (Genre *)(*seek);

    DeleteGenre(genre);

    EHArrayErase(app->genres,seek);

}

 

void AppListGenre(App *app)

{

    Iterator seek= EHArrayBegin(app->genres);

    Iterator end= EHArrayEnd(app->genres);

    Genre *sgenre=0;

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

    {

        sgenre = (Genre *)(*seek);

        GenreView(sgenre);

    }

}

 

void AppListBookAtGenre(App *app)

{

    char gname[MAX_GNAME_LEN+1]="";

    Iterator seek = 0;

    Genre *genre = 0;

    AppListGenre(app);

    printf("도서 목록을 확인할 장르명을 입력하세요.\n");

    gets_s(gname,MAX_GNAME_LEN);

    seek = AppFindGenre(app,gname);

    if(seek == EHArrayEnd(app->genres))

    {

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

        return;

    }

    genre = (Genre *)(*seek);

    GenreViewAll(genre);

}

 

void AppAddBook(App *app)

{

    char gname[MAX_GNAME_LEN+1]="";

    char author[MAX_ANAME_LEN+1]="";

    char title[MAX_TNAME_LEN+1]="";

    Iterator seek = 0;

    Genre *genre = 0;

    AppListGenre(app);

    printf("도서를 추가할 장르명을 입력하세요.\n");

    gets_s(gname,MAX_GNAME_LEN);

    seek = AppFindGenre(app,gname);

    if(seek == EHArrayEnd(app->genres))

    {

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

        return;

    }

    printf("도서명을 입력하세요.\n");

    gets_s(title,MAX_TNAME_LEN);

    printf("저자명을 입력하세요.\n");

    gets_s(author,MAX_ANAME_LEN);

    genre = (Genre *)(*seek);

    GenreAddBook(genre,title,author);

}

void AppFindBookByNum(App *app)

{

    char gname[MAX_GNAME_LEN+1]="";

    int bnum=0;

    Iterator seek = 0;

    Genre *genre = 0;

    Book *book = 0;

    AppListGenre(app);

    printf("검색할 장르명을 입력하세요.\n");

    gets_s(gname,MAX_GNAME_LEN);

    seek = AppFindGenre(app,gname);

    if(seek == EHArrayEnd(app->genres))

    {

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

        return;

    }

    printf("도서 번호를 입력하세요.\n");

    scanf_s("%d", &bnum);

    genre = (Genre *)(*seek);

    book = GenreFindBookByNum(genre,bnum);

    if(book)

    {

        BookView(book);

    }

    else

    {

        printf("도서를 찾지 못했습니다.\n");

    }

}

void AppFindBookByTitle(App *app)

{

    char gname[MAX_GNAME_LEN+1]="";

    char title[MAX_TNAME_LEN+1]="";

    Iterator seek = 0;

    Genre *genre = 0;

    Book *book = 0;

 

    AppListGenre(app);

    printf("검색할 장르명을 입력하세요.\n");

    gets_s(gname,MAX_GNAME_LEN);

    seek = AppFindGenre(app,gname);

    if(seek == EHArrayEnd(app->genres))

    {

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

        return;

    }

    printf("도서 제목을 입력하세요.\n");

    gets_s(title,MAX_TNAME_LEN);

    genre = (Genre *)(*seek);

    book = GenreFindBookByTitle(genre,title);

    if(book)

    {

        BookView(book);

    }

    else

    {

        printf("도서를 찾지 못했습니다.\n");

    }

}

void AppListAll(App *app)

{

    Iterator seek= EHArrayBegin(app->genres);

    Iterator end= EHArrayEnd(app->genres);

    Genre *genre=0;

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

    {

        genre = (Genre *)(*seek);

        GenreViewAll(genre);

    }

}

 

void DeleteApp(App *app)

{

    AppSave(app);

    AppTApp(app);

    free(app);

}

void AppTApp(App *app)

{

    DeleteEHArray(app->genres);

}

 

void AppSerialize(App *app,FILE *fp);

void AppSave(App *app)

{

    FILE *fp = 0;

    fopen_s(&fp, app->fname,"w");

    if(fp)

    {

        AppSerialize(app,fp);

    }

    else

    {

       printf("오류!!!데이터 저장 실패\n");

    }

}

 

void AppSerialize(App *app,FILE *fp)

{

    Iterator seek;

    Iterator end;

    int n = 0;

    Genre *genre=0;

    fwrite(&(app->last_gnum),sizeof(int),1,fp);

    n = EHArrayGetSize(app->genres);

    fwrite(&n,sizeof(int),1,fp);

    seek= EHArrayBegin(app->genres);

    end= EHArrayEnd(app->genres);

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

    {

        genre = (Genre *)(*seek);

        GenreSerialize(genre,fp);

    }

}

 

//Program.c

#include "App.h"

#define DEF_FNAME    "member.ehd"

int main(int argc, char **argv)

{

    App *app = 0;

    if(argc != 2)

    {

        app = NewApp(DEF_FNAME);

    }

    else

    {

        app = NewApp(argv[1]);

    }

    AppRun(app);

    DeleteApp(app);

    return 0;

}

반응형