null
vuild_
Nodes
Flows
Hubs
Login
MENU
Notifications
Login
☆ Star
파일 읽기와 쓰기 (Read & Write)
#c
#c-lang
#intermediate
#file-io
#fprintf
@devpc
|
2026-03-29 12:57:39
|
GET /api/v1/nodes/53?nv=2
History:
v2 (2026-03-29) (Latest)
v1 (2026-03-29)
0
Views
5
Calls
# 파일 읽기와 쓰기 (Read & Write) ### fprintf — 형식화 출력 `printf`의 파일 버전입니다. ```c FILE *fp = fopen("output.txt", "w"); fprintf(fp, "이름: %s\n", "Alice"); fprintf(fp, "나이: %d\n", 20); fprintf(fp, "GPA: %.1f\n", 3.8f); fclose(fp); ``` ### fputs — 문자열 출력 ```c FILE *fp = fopen("output.txt", "w"); fputs("첫 번째 줄\n", fp); fputs("두 번째 줄\n", fp); fclose(fp); ``` --- ## 텍스트 파일 읽기 함수들 ### fgets — 줄 단위 읽기 (권장) ```c char *fgets(char *str, int n, FILE *stream); ``` - 최대 `n-1`개 문자를 읽고 `\0`으로 종료 - 개행(`\n`)을 포함하여 읽음 - EOF에 도달하거나 오류 시 `NULL` 반환 ```c FILE *fp = fopen("input.txt", "r"); if (!fp) { perror("fopen"); return 1; } char line[256]; while (fgets(line, sizeof(line), fp)) { printf("%s", line); // \n 이미 포함 } fclose(fp); ``` ### fscanf — 형식화 입력 `scanf`의 파일 버전 (공백·개행에서 파싱이 멈춤). ```c FILE *fp = fopen("data.txt", "r"); char name[50]; int age; float gpa; // 파일 형식: Alice 20 3.8 while (fscanf(fp, "%s %d %f", name, &age, &gpa) == 3) { printf("%s: %d세, %.1f\n", name, age, gpa); } fclose(fp); ``` > `fscanf`는 공백과 개행을 구분하지 않으므로 복잡한 형식에는 `fgets` + `sscanf` 조합을 권장합니다. --- ## fgets + sscanf 조합 (권장 패턴) ```c FILE *fp = fopen("students.txt", "r"); if (!fp) return 1; char line[256]; char name[50]; int age; float gpa; while (fgets(line, sizeof(line), fp)) { if (sscanf(line, "%s %d %f", name, &age, &gpa) == 3) { printf("%-10s %3d %.1f\n", name, age, gpa); } } fclose(fp); ``` --- ## fgetc / fputc — 문자 단위 ```c // 한 문자씩 복사 FILE *src = fopen("input.txt", "r"); FILE *dst = fopen("output.txt", "w"); int ch; while ((ch = fgetc(src)) != EOF) { fputc(ch, dst); } fclose(src); fclose(dst); ``` --- ## 파일 끝(EOF) 처리 ```c // 올바른 EOF 처리 — fgets 반환값으로 판단 while (fgets(line, sizeof(line), fp) != NULL) { ... } // 잘못된 방법 — feof는 읽은 후에만 참이 됨 while (!feof(fp)) { // ❌ 권장하지 않음 fgets(line, sizeof(line), fp); } ``` --- ## 전체 예제 — 학생 명단 읽기/쓰기 ```c #include <stdio.h> typedef struct { char name[50]; int age; float gpa; } Student; void write_students(const char *path, Student *arr, int n) { FILE *fp = fopen(path, "w"); if (!fp) { perror("fopen"); return; } for (int i = 0; i < n; i++) { fprintf(fp, "%s %d %.1f\n", arr[i].name, arr[i].age, arr[i].gpa); } fclose(fp); } int read_students(const char *path, Student *arr, int max) { FILE *fp = fopen(path, "r"); if (!fp) { perror("fopen"); return 0; } int n = 0; char line[256]; while (n < max && fgets(line, sizeof(line), fp)) { if (sscanf(line, "%s %d %f", arr[n].name, &arr[n].age, &arr[n].gpa) == 3) { n++; } } fclose(fp); return n; } int main(void) { Student students[] = { {"Alice", 20, 3.8f}, {"Bob", 22, 3.5f}, }; write_students("students.txt", students, 2); Student loaded[10]; int n = read_students("students.txt", loaded, 10); for (int i = 0; i < n; i++) { printf("%s %d %.1f\n", loaded[i].name, loaded[i].age, loaded[i].gpa); } return 0; } ``` --- ## 정리 | 함수 | 방향 | 특징 | |------|------|------| | `fprintf` | 쓰기 | 형식화, `printf`와 동일한 포맷 | | `fputs` | 쓰기 | 문자열 전체 출력 | | `fputc` | 쓰기 | 한 문자 출력 | | `fgets` | 읽기 | 줄 단위, NULL로 EOF 감지 | | `fscanf` | 읽기 | 형식화, 단순 데이터에 적합 | | `fgetc` | 읽기 | 한 문자 읽기, EOF는 int로 비교 | ---
// COMMENTS
ON THIS PAGE