C언어 바이너리파일 읽기, 쓰기

2018. 12. 19. 00:40개발노트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct student
{
    char name[10];
    int kor, eng, mat;
    double avg;
    //int rank;
};
typedef struct student student;
 
int main()
{
    FILE *fout, *fout_2;
    //struct student s[3];
    struct student *s; //동적할당시에는 배열로 안줌 
 
    fout = fopen("student.bin""rb");
    fout_2 = fopen("studentout.bin""w+b");
cs


구조체를 만들어주고 파일도 열어줍니다.

바이너리 파일을 읽어 올 때는 "rb" (만들어진 바이너리 파일이 있어야 합니다.)

바이너리 파일을 만들고 내용을 넣기위해 "w+b"로 파일을 열었습니다.


1
2
3
4
 
    fseek(fout, 0, SEEK_END);
    int count = ftell(fout) / sizeof(student);
    s = (student *)malloc(sizeof(student)*count);
cs


fseek함수는 개방된 파일에서 파일 포인터의 위치를 지정해주는 함수입니다.


fseek(fout, 0, SEEK_END); 일 떄


fout -> stream작업을 수행할 스트림의 FILE 객체를 가리키는 포인터

0 -> offsetorgin 으로 부터 얼마나 떨어진 곳에 설정할 지에 대한 값

SEEK_END -> origin오프셋이 더해지는 위치로, <stdio.h> 에 정의된 다음과 같은 매크로 상수들을 이용한다.

상수

설명

SEEK_SET

파일의 시작

SEEK_CUR

현재 파일 포인터의 위치

SEEK_END

파일의 끝


ftell함수와 sizeof 함수로 count를 구했는데

ftell함수는 현재 포인터 위치를 구하는 함수입니다.

malloc으로 동적 메모리 할당해줍니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

    fread(s, sizeof(student) * count, 1, fout);
 
    //평균계산
    for (int i = 0; i < count; i++) {
        s[i].avg = (s[i].kor + s[i].eng + s[i].mat) / 3.0;
        printf("%-4s % 4d % 4d % 4d %5.1f %d\n", s[i].name, s[i].kor, s[i].eng, s[i].mat, s[i].avg);
    }
    puts("이진화일 저장 후 출력------");
    fwrite(s, sizeof(student)*count, 1, fout_2);
    rewind(fout_2);
 
    student user;
    while (fread(&user, sizeof(student), 1, fout_2) == 1)
        printf("%-4s %4d %4d %4d %5.1f %d\n", user.name, user.kor, user.eng, user.mat, user.avg);
 
    fclose(fout);
    fclose(fout_2);
    free(s);
    return 0;
}
cs


fread로  이진화된 바이너리파일을 가져옵니다.

인수를 살펴보자면

s 는 입력받은 데이터를 저장할 버퍼의 주소

sizeof(student) * count 는 원소 1개의 크기

1 은 입력 받을 원소의 개수

fout는 읽어올 파일을 의미합니다.


for문으로는 입력된 값들을 불러와 평균을 계산하고 출력합니다.

while문으로는 파일이 끝날 때 까지 출력합니다.


%4d %-4s 형식으로 출력한건 자릿수를 맞추기 위해서입니다.