113. 도서 관리 프로그램 – 저장

이번에는 데이터를 파일에 저장하는 기능의 시퀀스 다이어그램을 작성하기로 해요.

먼저 App에서는 파일을 쓰기 모드로 열어야겠죠.
그리고 App의 정보를 파일에 저장해요.
프로그램의 데이터를 다른 물리 매체에 선형으로 보내는 것을 직렬화라고 불러요.
직렬화 함수에서는 마지막 부여한 장르 번호와 배열에 보관한 장르 개수를 저장하세요

그리고 배열에 보관한 장르들의 정보를 파일에 직렬화하세요.
장르의 정보를 직렬화하는 함수에서도 장르번호, 장르명, 마지막 부여한 도서 번호를 파일에 저장하고 배열에 보관한 도서 개수를 저장하세요.

그리고 배열에 보관한 모든 장르를 파일에 직렬화하세요.
파일의 정보를 직렬화하는 함수에서는 자신의 정보를 저장하세요.
이와 같은 작업을 완료하면  App에서는 파일을 닫아야겠죠.

먼저 Book 헤더에 직렬화 함수를 선언하고 소스 파일에 함수를 구현하세요.
Book 개체의 모든 정보는 연속적인 메모리에 있으므로 fwrite 한 번만 호출하세요.

void BookSerialize(Book *book,FILE *fp)
{
    fwrite(book,sizeof(Book),1,fp);
}

Genre 헤더에도 직렬화 함수를 선언하고 소스 파일에 함수를 구현하세요.
Genre 개체 내부에는 도서를 보관하는 배열이 있어요.
따라서 Genre의 정보는 한 번에 저장할 수 없어요.
먼저 장르 이름, 장르 번호, 최근에 부여한 도서 번호를 저장하세요.
그리고 배열에 보관한 도서 개수를 얻어와서 파일에 저장하세요.
마지막으로 배열에 보관한 도서들의 정보를 직렬화하세요.

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에 Save 함수를 구현해 봐요.
먼저 파일을 쓰기 모드로 열어야겠죠.
그리고 정상적으로 열었다면 직렬화 함수를 호출하세요.

void AppSave(App *app)
{
    FILE *fp = 0;
    fopen_s(&fp, app->fname,"w");
    if(fp)
    {
        AppSerialize(app,fp);
        fclose(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);
    }
}