강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

jm8193abc님의 프로필 이미지
jm8193abc

작성한 질문수

홍정모의 따라하며 배우는 C언어

14.14 구조체 파일 입출력 연습문제

14.14 예제 질문

작성

·

41

1

#define CRTSECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#define SLEN 101

struct book

{

char name[SLEN];

char author[SLEN];

};

void print_books(const struct book* books, int n);

void write_books(const char* filename, const struct book* books, int n);

struct book* read_books(const char* filename, int* n);

int main()

{

int temp;

int n = 3;

struct book* my_books = (struct book*)malloc(sizeof(struct book) * n);

if (!my_books) {

printf("Malloc failed");

exit(1);

}

my_books[0] = (struct book){ "The Great Gatsby", "F. Scott Fitzgerald" };

my_books[1] = (struct book){ "Hamlet", "William Shakespeare" };

my_books[2] = (struct book){ "The Odyssey", "Homer" };

print_books(my_books, n);

printf("\nWriting to a file.\n");

write_books("books.txt", my_books, n);

free(my_books);

n = 0;

printf("Done.\n");

printf("\nPress any key to read data from a file.\n\n");

temp = _getch();

my_books = read_books("books.txt", &n);

print_books(my_books, n);

free(my_books);

n = 0;

return 0;

}

void print_books(const struct book* books, int n)

{

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

{

printf("Book %d : \"%s\" written by \"%s\"\n", i + 1, books[i].name, books[i].author);

}

}

void write_books(const char* filename, const struct book* books, int n)

{

FILE* fw;

if ((fw = fopen(filename, "w")) == NULL)

{

fprintf(stderr, "Can't open \"%s\" file.\n", filename);

exit(EXIT_FAILURE);

}

fwrite(books, sizeof(struct book), n, fw);

fclose(fw);

}

struct book* read_books(const char* filename, int* n)

{

FILE* fp;

if ((fp = fopen(filename, "r")) == NULL)

{

fprintf(stderr, "Can't open \"%s\" file.\n", filename);

exit(EXIT_FAILURE);

}

fseek(fp, 0, SEEK_END);

long file_size = ftell(fp);

rewind(fp);

struct book* all_books;

int si = file_size / sizeof(struct book);

*n = si;

all_books = (struct book*)malloc(sizeof(struct book) (n));

if (all_books == NULL)

{

printf("Failed");

return NULL;

}

fread(all_books, sizeof(struct book), *n, fp);

fclose(fp);

return all_books;

}

예제를 풀다보니 바이너리형식으로 추가,저장되는 코드로 만들어 버렸는데 이 경우에는 메모장에서 텍스트를 추가할 수 없으니 틀렸다고 보는게 맞겠죠?

 

답변 1

0

안녕하세요? 질문&답변 도우미 durams입니다.

바이너리 형식이라는 개념에 대해 오해가 있으신 것 같습니다. 텍스트 파일도 결국 컴퓨터에 저장되는 값들은 이진 값들이며, 텍스트 파일 뷰어 프로그램(예 : 메모장)으로 보는 경우 이를 인코딩하여 사람이 인식할 수 있는 문자열 형태로 보인다는 것을 이해하셔야 합니다.

또한 바이너리 형식바이너리 모드로 파일을 여는 것은 다르게 보아야 합니다.

  • 바이너리 형식 : 파일에 데이터가 저장된 방식.

  • 바이너리 모드로 파일을 여는 것 : fopen으로 파일을 열 때, mode에 "b"를 지정하는 것.

     

바이너리 형식으로 추가/저장되는 코드를 작성했다고 하셨지만, 제시해주신 코드를 보면 fopen에서 바이너리 모드를 사용하지는 않으며, 강의에서 제시한 정답 코드와의 주된 차이점은 입출력 함수로 fprintf/fscanf를 사용한 것 대신에 fwrite/fread를 사용했다는 점입니다. fprintffscanf는 문자열에 대해 동작하도록 설계된 함수이기 때문에 개행 문자에 대한 처리가 자동으로 이루어지지만, fwritefread는 그렇지 않습니다.

바이너리 모드로 열고 fwritefread로 입출력을 진행하더라도, 메모장에서 얼마든지 읽기/쓰기가 가능합니다. 위 코드를 실행했을 때 제대로 동작하지 않았던 이유는 개행 문자에 대한 고려가 없었기 때문입니다.

프로그램이 제대로 동작하도록 충분히 고민하며 현 코드를 수정해보시고, 그래도 잘 모르겠다면 다시 질문주세요.

 

jm8193abc님의 프로필 이미지
jm8193abc

작성한 질문수

질문하기