인프런 커뮤니티 질문&답변
14.14 예제 질문
작성
·
53
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를 사용했다는 점입니다. fprintf와 fscanf는 문자열에 대해 동작하도록 설계된 함수이기 때문에 개행 문자에 대한 처리가 자동으로 이루어지지만, fwrite와 fread는 그렇지 않습니다.
바이너리 모드로 열고 fwrite와 fread로 입출력을 진행하더라도, 메모장에서 얼마든지 읽기/쓰기가 가능합니다. 위 코드를 실행했을 때 제대로 동작하지 않았던 이유는 개행 문자에 대한 고려가 없었기 때문입니다.
프로그램이 제대로 동작하도록 충분히 고민하며 현 코드를 수정해보시고, 그래도 잘 모르겠다면 다시 질문주세요.





