I/O란 C 언어에서 데이터를 읽고 쓰는 입력·출력(Input/Output) 작업을 처리하는 함수를 의미합니다. C 언어의 파일 입출력은 처리 방식에 따라 고수준(High level) I/O와 저수준(Low level) I/O로 나눌 수 있습니다.
고수준 I/O와 저수준 I/O의 차이
고수준 I/O (High Level I/O)
- 사람이 이해하고 사용하기 쉬운 형태로 제공됩니다.
- 가장 큰 장점은 이식성(portability)이 높아 다양한 시스템에서 동일하게 동작한다는 점입니다.
저수준 I/O (Low Level I/O)
- 컴퓨터(시스템) 중심으로 동작하여 사람이 이해하기 어렵습니다.
- 장점은 처리 속도가 빠르고 실행 시간이 짧다는 것입니다.
- 단점은 운영체제나 하드웨어에 의존적이어서 이식성이 떨어진다는 것입니다.
C 언어의 주요 고수준 I/O 함수
대표적인 고수준 입출력 함수는 아래 표와 같습니다.
| 함수 | 설명 |
|---|---|
| fprintf() | 파일에 데이터를 씁니다. |
| fscanf() | 파일에서 데이터를 읽어옵니다. |
| putc() / fputc() | 파일에 한 문자를 씁니다. |
| getc() / fgetc() | 파일에서 한 문자를 읽어옵니다. |
| putw() | 파일에 정수를 씁니다. |
| getw() | 파일에서 정수를 읽어옵니다. |
| fputs() | 파일에 문자열을 씁니다. |
| fgets() | 파일에서 문자열을 읽어옵니다. |
| fread() | 파일에서 레코드 전체를 한 번에 읽어옵니다. |
| fwrite() | 파일에 레코드 전체를 한 번에 씁니다. |
fprintf()와 fscanf() 함수
fprintf()는 printf()와 사용법이 유사하지만, 출력 결과를 화면이 아닌 파일에 저장한다는 점이 다릅니다.
문법은 다음과 같습니다.
fprintf(파일 포인터, "제어 문자열", 변수 목록);
사용 예시:
FILE *fp; fprintf(fp, "%d%c", a, b);
fscanf()는 scanf()와 유사하며, 키보드 입력 대신 파일에서 데이터를 읽어옵니다.
문법은 다음과 같습니다.
fscanf(파일 포인터, "제어 문자열", &변수 목록);
사용 예시:
FILE *fp; fscanf(fp, "%d%c", &a, &b);
putc()와 getc() 함수
putc()는 파일에 한 문자를 출력(저장)할 때 사용합니다.
문법은 다음과 같습니다.
putc(char ch, FILE *fp);
사용 예시:
FILE *fp; char ch; putc(ch, fp);
getc()는 파일에서 한 문자를 읽어올 때 사용합니다.
문법은 다음과 같습니다.
char getc(FILE *fp);
사용 예시:
FILE *fp; char ch; ch = getc(fp);
putw()와 getw() 함수
putw()는 파일에 정수 하나를 출력할 때 사용합니다.
문법은 다음과 같습니다.
putw(int num, FILE *fp);
사용 예시:
FILE *fp; int num; putw(num, fp);
getw()는 파일에서 정수 하나를 읽어올 때 사용합니다.
문법은 다음과 같습니다.
int getw(FILE *fp);
사용 예시:
FILE *fp; int num; num = getw(fp);
fputc()와 fgetc() 함수
fputc()는 파일에 한 문자를 쓸 때 사용하며, putc()와 거의 같은 역할을 합니다.
문법은 다음과 같습니다.
fputc(char ch, FILE *fp);
사용 예시:
FILE *fp; char ch; fputc(ch, fp);
fgetc()는 파일에서 한 문자를 읽어올 때 사용합니다.
문법은 다음과 같습니다.
int fgetc(FILE *fp);
사용 예시:
FILE *fp; char ch; ch = fgetc(fp);
fgets()와 fputs() 함수
fgets()는 파일에서 문자열을 읽어올 때 사용합니다.
문법은 다음과 같습니다.
fgets(문자열 변수, 읽을 문자 수, 파일 포인터);
사용 예시:
FILE *fp; char str[30]; fgets(str, 30, fp);
fputs()는 파일에 문자열을 쓸 때 사용합니다.
문법은 다음과 같습니다.
fputs(문자열 변수, 파일 포인터);
사용 예시:
FILE *fp; char str[30]; fputs(str, fp);
fread()와 fwrite() 함수
fread()는 구조체 등으로 구성된 레코드 전체를 한 번에 읽어올 때 사용합니다.
문법은 다음과 같습니다.
fread(&구조체 변수, sizeof(구조체 변수), 레코드 개수, 파일 포인터);
사용 예시:
struct emp {
int eno;
char ename[30];
float sal;
} e;
FILE *fp;
fread(&e, sizeof(e), 1, fp);
fwrite()는 레코드 전체를 한 번에 파일에 저장할 때 사용합니다.
문법은 다음과 같습니다.
fwrite(&구조체 변수, sizeof(구조체 변수), 레코드 개수, 파일 포인터);
사용 예시:
struct emp {
int eno;
char ename[30];
float sal;
} e;
FILE *fp;
fwrite(&e, sizeof(e), 1, fp);
실습 예제 1: putw()와 getw()로 숫자 저장 및 출력
다음은 1부터 10까지의 숫자를 파일에 저장한 후, 다시 읽어서 화면에 출력하는 C 프로그램입니다.
// 1부터 10까지의 숫자를 파일에 저장하고 다시 출력하는 프로그램
#include<stdio.h>
int main() {
FILE *fp;
int i;
fp = fopen("num.txt", "w");
for (i = 1; i <= 10; i++) {
putw(i, fp);
}
fclose(fp);
fp = fopen("num.txt", "r");
printf("file content is");
for (i = 1; i <= 10; i++) {
i = getw(fp);
printf("%d", i);
}
fclose(fp);
return 0;
}
실행 결과
위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
file content is12345678910
실습 예제 2: fread()와 fwrite()로 학생 정보 저장 및 출력
다음은 학생 정보를 구조체 배열에 입력받아 파일에 저장한 후, fwrite()로 기록하고 fread()로 다시 읽어 화면에 출력하는 C 프로그램입니다.
#include<stdio.h>
struct student {
int sno;
char sname[30];
float marks;
char temp;
};
main() {
struct student s[60];
int i;
FILE *fp;
fp = fopen("student1.txt", "w");
for (i = 0; i < 2; i++) {
printf("enter details of student %d\n", i + 1);
printf("student number:");
scanf("%d", &s[i].sno);
scanf("%c", &s[i].temp);
printf("student name:");
gets(s[i].sname);
printf("student marks:");
scanf("%f", &s[i].marks);
fwrite(&s[i], sizeof(s[i]), 1, fp);
}
fclose(fp);
fp = fopen("student1.txt", "r");
for (i = 0; i < 2; i++) {
printf("details of student %d are\n", i + 1);
fread(&s[i], sizeof(s[i]), 1, fp);
printf("student number = %d\n", s[i].sno);
printf("student name = %s\n", s[i].sname);
printf("marks = %f\n", s[i].marks);
}
fclose(fp);
getch();
}
실행 결과
위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
enter details of student 1 student number:1 student name:bhanu student marks:50 enter details of student 2 student number:2 student name:priya student marks:69 details of student 1 are student number = 1 student name = bhanu marks = 50.000000 details of student 2 are student number = 2 student name = priya marks = 69.000000
마무리
지금까지 살펴본 것처럼 C 언어의 고수준 I/O 함수는 문자, 정수, 문자열, 구조체 레코드 등 다양한 형태의 데이터를 파일에 손쉽게 읽고 쓸 수 있도록 도와줍니다. 특히 fread()와 fwrite()를 활용하면 구조체 단위의 데이터를 한 번에 처리할 수 있어, 학생 정보 관리처럼 여러 필드를 가진 데이터를 다룰 때 매우 유용합니다. 각 함수의 문법과 예제를 직접 실습해 보면서 파일 입출력에 대한 이해를 깊이 해 보시기 바랍니다.