14.14 예제 질문
56
작성한 질문수 2
#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로 입출력을 진행하더라도, 메모장에서 얼마든지 읽기/쓰기가 가능합니다. 위 코드를 실행했을 때 제대로 동작하지 않았던 이유는 개행 문자에 대한 고려가 없었기 때문입니다.
프로그램이 제대로 동작하도록 충분히 고민하며 현 코드를 수정해보시고, 그래도 잘 모르겠다면 다시 질문주세요.
완전히 똑같이 따라해도 exe파일이 안만들어져서 실행이 안됩니다.
1
43
3
main 함수에서 왜 int만 선언이 되는걸까요
1
51
2
8비트 2진수 변환시 왜 1을 더해야하나요?
1
52
2
혹시 강의를 빠르게 수강하려면 어디서부터 듣는게 좋을까요?
1
46
1
프로토타입과 함수간의 인자 불일치
1
72
2
12.12 헤더 관련 질문
1
59
2
Visual Studio Community 2026 사용 문의
1
132
2
Q. 15:30, 부호가 있는 8비트 정수 질문
1
59
2
getchar(), putchar()
1
92
3
강의자리ㅛ
1
78
2
비주얼스튜디오코드로 공부해도 상관없나요?
1
112
2
소스파일안에 여러 파일
1
74
2
F5와 F7의 차이
1
75
2
c = TWO * (a+b); 에서 a와 b는?
1
58
2
; 세미콜론을 붙이는 기준에 문의
1
68
1
Step over 기능 문의
1
52
2
2.6 강의 따옴표 출력 규칙 문의
1
74
2
int main 함수 관련 오류 문의
1
67
2
13.4 words[0]
0
60
2
11.7 함수를 구현해 봤습니다.
1
62
2
11.6 직접 strcmp와 strncmp를 구현해 보았습니다.
1
64
2
11.6 my_strcat과 my_strncat을 구현해봤습니다.
1
53
2
11.6 fit_str함수를 구현해 봤습니다.
1
53
2
11.5 코드 구현
1
66
2





