DX라이브러리2014. 12. 30. 14:35

3.11 세이브데이터 만드는법


* 원본에서도 3.8 ~ 3.10은 없습니다.


C언어 입문시에 파일출력하는 법을 배우게 된다. 


FILE *fp = fopen( "***.txt", "w" );


위 명령줄을 통해 파일을 열고


int money = 1000;

fprintf( fp, "현재 소지금 = %d\n", money );


과 같은 명령줄을 사용하게되면 실제 파일에는 아래 그림과 같이 저장된다.



하지만 이런 방식으로는 데이터가 너무 쉽게 개조가 가능해지며 데이터의 양이 몇백, 몇천이상이 되었을 때 매우 번거로워진다. 때문에 텍스트 파일이 아닌 바이너리 파일로 출력을 하는것이 좋다. 이  fopen함수의 역할을 확인해보자.


FILE *fp = fopen( "***.dat", "wb" );


이 명령줄처럼 "b"를 붙이게 되면 바이너리파일로 출력된다. 바이너리 파일에 데이터를 출력하는 함수는 fwrite함수이며 각각 인수는 아래와 같이 설명 가능하다.


제 1인수 : 세이브 데이터를 갖게되는 변수의 어드레스

제 2인수 : 출력할 bite수

제 3인수 : 출력 갯수

제 4인수 : 출력할 파일 포인터


위에서 살펴본 money변수에 저장된 int형 값을 출력하고 싶을 때에는 아래 명령줄과 같다.


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


실행 예제를 작성해보면 다음과 같다.


#include <stdio.h>


int main(){

        int money = 1000;

        FILE *fp = fopen( "savedata.dat", "wb" ); // 파일 열기

        if( fp == NULL ){ // NULL이 반환되면 종료

                return 0;

        }

        fwrite( &money, sizeof(int), 1, fp ); // 파일에 money의 값을 출력

        fclose( fp ); //파일 닫기

        return 0;

}


실행결과



이 예제는 DX라이브러리를 사용하지 않기 때문에 별도의 프로젝트를 생성해서 테스트해보자. 참고로 필자는 데브C++을 사용해서 테스트했다. 프로그램을 실행해보면 savedata.dat라는 파일이 생성되며 메모장을 통해 열어보아도 내용 확인이 되지 않는다. (다만, 바이너리 에디터로 열게되면 텍스트파일과 마찬가지로 편집 가능해지기는 하다.) 세이브데이터는 하나씩 출력하면 매우 번거롭다. 따라서 구조체를 이용하여 한번에 출력하는 것이 편하다. 예를들어 세이브하고싶은 데이터에 HP, MP, 소지금, 경험치의 4종류의 데이터가 있다고 가정하면 이 것을 한개의 구조체로 만들고 fwrite함수를 통해서 한번에 출력한다.


#include <stdio.h>


typedef struct{

        int HP;         //HP

        int MP;         //MP

        int Money;      //소지금

        int Exp;        //경험치

}SaveData_t;


int main(){

        SaveData_t Data = { 200, 100, 1000, 1000 };

        FILE *fp = fopen( "savedata.dat", "wb" );

        if( fp == NULL ){

                return 0;

        }

        fwrite( &Data, sizeof(Data), 1, fp ); // SaveData_t구조체 내용을 출력

        fclose( fp );

        return 0;

}


생성된 파일을 열어보면 다음과 같다.



int형의 값들이 네개 저장되어있는것을 확인 가능하다. 다음은 출력한 데이터를 읽어들이는 프로그램을 만들어보자. fwrite함수는 출력을 담당했었고 이에 대응하여 입력은 fread함수가 담당한다. 인수부분은 fwrite와 동일하다. 위 예제에서 출력된 세이브파일을 읽어들여보자.


#include <stdio.h>


typedef struct{

        int HP;         //HP

        int MP;         //MP

        int Money;      //소지금

        int Exp;        //경험치

}SaveData_t;


int main(){

        SaveData_t Data;

        FILE *fp = fopen( "savedata.dat", "rb" );

        if( fp == NULL ){

                return 0;

        }

        fread( &Data, sizeof(Data), 1, fp );

        fclose( fp );


        printf("HP=%d\nMP=%d\n소지금=%d\n경험치=%d\n",

                Data.HP, Data.MP, Data.Money, Data.Exp );


        return 0;

}


실행결과



세이브파일 작성시의 예제와 차이점은 fopen에서의 파일 오픈 방법을 쓰기 방식의 w에서 읽기 방식의 r로 변환한 것 뿐이다. 이후는 fwrite를 fread로 변경했다. 파일 출력시와 마찬가지로 정상적으로 값을 불러오는 것을 알 수 있다. 세이브파일 제작시에는 구조체를 사용하자.



Posted by 캡슐리어