C언어 프로그래밍에서 데이터를 단순히 화면에 출력하는 것을 넘어, 파일에 표 형식으로 저장하거나 저장된 데이터를 다시 읽어오는 기능은 매우 중요합니다. 이때 가장 강력한 도구가 바로 포맷팅(Formatting) 입출력 함수인 fprintf와 fscanf입니다.
오늘은 이 두 함수의 기본 개념부터 보안 사고를 예방하는 안전한 사용법까지 정리해 보겠습니다.

1. fprintf와 fscanf 개요
이 두 함수는 우리가 익히 아는 printf, scanf와 동작 방식이 거의 같습니다. 차이점은 입출력 대상이 '콘솔'이 아니라 '파일 스트림'이라는 점입니다.
1.1 fprintf: 형식에 맞춰 파일에 쓰기
fprintf는 변수의 값을 특정 형식(정수, 실수, 문자열 등)으로 변환하여 파일에 기록합니다.
- 함수 원형: int fprintf(FILE *stream, const char *format, ...);
- 특징: 로그 파일 작성, 데이터 리포트 생성 등에 주로 사용됩니다.
1.2 fscanf: 형식에 맞춰 파일에서 읽기
fscanf는 파일에서 데이터를 읽어 지정된 서식에 따라 변수에 저장합니다.
- 함수 원형: int fscanf(FILE *stream, const char *format, ...);
- 특징: 설정 파일 읽기, 저장된 데이터베이스 로드 등에 유용합니다.
2. 기본 예제: 학생 정보 저장 및 불러오기
학생의 ID, 이름, 성적을 파일에 기록하고 다시 읽어오는 실습 코드입니다.
#include <stdio.h>
int main() {
FILE *file;
int id;
char name[20];
float score;
// 1. 파일 쓰기 (student.txt 생성)
file = fopen("student.txt", "w");
if (file == NULL) {
perror("파일 개방 에러");
return 1;
}
fprintf(file, "%d %s %.2f\n", 101, "Kim", 95.5);
fprintf(file, "%d %s %.2f\n", 102, "Lee", 88.0);
fclose(file);
// 2. 파일 읽기
file = fopen("student.txt", "r");
if (file == NULL) {
perror("파일 읽기 에러");
return 1;
}
printf("%-5s %-10s %-5s\n", "ID", "Name", "Score");
printf("--------------------------\n");
// fscanf의 반환값이 읽어들인 항목 개수임을 활용
while (fscanf(file, "%d %s %f", &id, name, &score) == 3) {
printf("%-5d %-10s %-5.2f\n", id, name, score);
}
fclose(file);
return 0;
}
3. 응용: 무제한 데이터 반복 처리
데이터의 개수를 미리 알 수 없을 때는 while문과 EOF를 조합하여 파일 끝까지 데이터를 파싱할 수 있습니다.
#include <stdio.h>
int main() {
FILE *fp = fopen("data.txt", "r");
if (!fp) return 1;
int val, count = 0;
printf("데이터 로드 중...\n");
while (fscanf(fp, "%d", &val) != EOF) {
printf("[%d번째 데이터]: %d\n", ++count, val);
}
fclose(fp);
return 0;
}
4. [보안 및 실무 팁] 주의사항 3가지
구글 검색 상위에 노출되는 좋은 기술 글은 '예외 상황'을 잘 다뤄야 합니다.
① fscanf의 버퍼 오버플로우 방지
%s로 문자열을 읽을 때 배열 크기를 넘어서는 데이터가 들어오면 프로그램이 중단될 수 있습니다.
- 해결책: fscanf(file, "%19s", name); 처럼 읽어올 최대 길이를 명시하세요.
② 반환값 확인의 습관화
fscanf는 성공적으로 읽은 항목의 개수를 반환합니다. 위 예제에서 == 3을 조건으로 준 이유는 ID, 이름, 성적 중 하나라도 잘못되면 읽기를 중단하여 잘못된 데이터 처리를 막기 위함입니다.
③ 파일 포인터 검사 (perror)
단순히 printf로 에러를 알리기보다 perror() 함수를 사용하면 시스템이 제공하는 구체적인 에러 메시지(파일 없음, 권한 부족 등)를 볼 수 있어 디버깅이 빨라집니다.
5. 결론
fprintf와 fscanf는 C언어 입출력의 꽃입니다. 이 함수들을 통해 텍스트 기반의 데이터 관리 시스템을 구축할 수 있으며, 이는 이후 XML이나 JSON 파싱의 기초가 됩니다.
오늘 다룬 안전한 사용법을 바탕으로 더 견고한 프로그램을 만들어보세요!
포스팅이 도움이 되셨다면 하트(♥)와 댓글 부탁드립니다!
임베디드 소프트웨어 및 최적화 기법에 대한 전문적인 정보는 'Coding by Head' 블로그에서 계속됩니다.
'Core Programming > C Standard Library: Resource & Performan' 카테고리의 다른 글
| C언어 파일 입출력 에러 처리 완벽 가이드 (perror, feof, ferror, clearerr) (0) | 2025.02.08 |
|---|---|
| C언어 파일 포인터 위치 제어: fseek, ftell, rewind 완벽 가이드 (0) | 2025.02.07 |
| C언어 파일 입출력 완벽 가이드: fopen부터 fread, fwrite 바이너리 활용까지 (0) | 2025.02.05 |
| C언어 파일 입출력 정복: fputs, fgets 함수 완벽 가이드 (예제 포함) (0) | 2025.02.04 |
| C언어 문자열 입출력 가이드: puts, gets 문제점과 fgets 완벽 대체법 (0) | 2025.02.03 |