파일은 우리가 실제로 흔히 아는 그 파일을 뜻합니다. C언어에서는 이러한 파일을 활용하여 입출력이 가능합니다. 지금껏 데이터를 변수에만 저장하여 활용했었는데요. 사실 변수에 저장한 데이터는 프로그램이 종료되면 유지되지 않기 때문에 영구적으로 기억할 수 없습니다. 그래서 이러한 파일을 사용할 수 있도록 C언어에서 지원을 하고 있습니다.
C에서는 스트림을 이용해서 모든 입출력이 가능하다고 했습니다. 그렇기 때문에 파일도 역시 스트림형태로 입출력이 이루어집니다. 스트림은 쉽게 말하면 다리같은 역할입니다. 출력장치나 입력장치와 프로그램을 연결합니다.

C언어에서의 파일은 2가지 유형으로 나누어집니다. 텍스트파일과 바이너리파일입니다.
텍스트파일은 일반적인 사람이 읽을 수 있는 파일입니다. 메모장 파일이나 프로그램의 소스파일과 같은 파일이 텍스트 파일의 예입니다. 문자들로 이루어져 있고 연속적인 라인으로 구성된 형태입니다.
바이너리파일은 사람이 읽을 수 없으나 컴퓨터가 읽을 수 있는 파일입니다. 프로그램 실행파일, 사운드 파일, 이미지 파일과 같은 파일이 바이너리 파일의 예입니다. 이진(0, 1)로만 이루어진 형태의 파일로 라인으로 분리되지않은 형태입니다.
파일은 크게 쓰기와 읽기로 나뉘어져있습니다. 두 개를 한 번에 할 수 없으므로 읽기모드를 쓰다가 쓰기모드로 바꾸고 싶을 땐, 읽기모드를 닫고 쓰기모드로 다시 열어야합니다.
예시
#include <stdio.h>
int main() {
FILE* fp;
fp = fopen("test.txt", "w"); // 파일을 쓰기 모드로 오픈
if (fp == NULL) {
printf("파일열기 실패\n");
return 0;
}
else {
printf("파일열기 성공\n");
}
fputc('a', fp); // 한문자 파일에 쓰기
fputc('b', fp);
for (int i = 'A'; i <= 'Z'; i++) {
fputc(i, fp);
}
fclose(fp); // 파일 닫기
fp = fopen("test.txt", "r"); // 읽기모드로 파일 오픈
if (fp == NULL) {
printf("파일 열기 실패\n");
return 0;
}
char c = 0;
while ((c = fgetc(fp)) != EOF) { // 파일에서 한문자씩 읽어서 콘솔창에 출력
putchar(c); // 한문자씩 출력
}
fclose(fp); // 파일 닫기
return 0;
}
결과
파일열기 성공
abABCDEFGHIJKLMNOPQRSTUVWXYZ


이런식으로 파일이 생성됩니다.
이번엔 문자열을 한번 입출력해보겠습니다.
예시
#include <stdio.h>
#include <memory.h>
#include <string.h>
int main() {
FILE* fp;
char file_buff[100];
fp = fopen("test_line.txt", "w");
if (fp == NULL) {
printf("파일 열기 실패\n");
return 0;
}
int i = 0;
for (i = 0; i < 3; i++) {
printf("%d번째 라인 내용을 입력하세요: ", i + 1);
memset(file_buff, 0, sizeof(file_buff)); //file_buff를 0으로 초기화
scanf("%s", file_buff);
file_buff[strlen(file_buff)] = '\n';
fputs(file_buff, fp); // 파일에 문자열을 쓴다.
}
fclose(fp);
printf("\n\n");
fp = fopen("test_line.txt", "r"); // 파일을 읽기모드로 열기
if (fp == NULL) printf("파일열기 실패\n");
// fgets: 파일에서 한라인씩 데이타를 읽는다. 없는 경우 NULL을 리턴
while (fgets(file_buff, sizeof(file_buff), fp) != NULL) {
printf("%s", file_buff);
memset(file_buff, 0, sizeof(file_buff)); //file_buff를 0으로 초기화
}
fclose(fp);
return 0;
}
결과
1번째 라인 내용을 입력하세요: Monster
2번째 라인 내용을 입력하세요: is
3번째 라인 내용을 입력하세요: strong
Monster
is
strong

3명의 유저정보(나이 이름 키)를 입력하여 text파일에 저장을 합니다. 다시 3명의 유저정보를 반환하고, 유저의 나이의 평균값을 구해보세요.
코드
#include <stdio.h>
int main() {
FILE* fp;
char name[20];
int age;
double height;
double ave_age = 0;
if ((fp = fopen("user_info.txt", "w")) == NULL) {
printf("파일 열기 실패\n");
return 0;
}
for (int i = 0; i < 3; i++) {
printf("%d번째 유저정보를 입력(나이 이름 키 순으로):", i + 1);
scanf("%d %s %lf", &age, name, &height);
fprintf(fp, "%d %s %lf\n", age, name, height);
}
fclose(fp);
if ((fp = fopen("user_info.txt", "r")) == NULL) {
printf("파일 열기 실패\n");
return 0;
}
for (int i = 0; i < 3; i++) {
fscanf(fp, "%d %s %lf", &age, name, &height);
printf("%d %s %lf\n", age, name, height);
ave_age += (double)age;
}
printf("유저들의 평균나이: %0.2lf\n", ave_age / 3);
fclose(fp);
}
결과
1번째 유저정보를 입력(나이 이름 키 순으로):26 이인혁 175
2번째 유저정보를 입력(나이 이름 키 순으로):27 신완수 178
3번째 유저정보를 입력(나이 이름 키 순으로):27 성홍주 178
26 이인혁 175.000000
27 신완수 178.000000
27 성홍주 178.000000
유저들의 평균나이: 26.67

바이너리와 텍스트의 차이점은 사람이 읽을 수 있냐 없냐입니다. 바이너리 파일에 정보를 넣고, 빼는건 텍스트와 다르지 않습니다.
예시
#include <stdio.h>
int main() {
int array[] = { 1000000, 20, 30, 40, 50 };
int outputArray[5];
FILE* fp;
int size, count;
fp = fopen("binary.bin", "wb");//바이너리 모드 파일쓰기로 파일 오픈
if (fp == NULL) {
printf("파일 열기 실패\n");
return 0;
}
size = sizeof(int);
count = sizeof(array) / sizeof(int);
fwrite(array, size, count, fp);//바이너리 모드로 파일쓰기
fclose(fp);
fp = fopen("binary.bin", "rb");//바이너리 모드 파일 읽기모드로 파일 오픈
if (fp == NULL) {
printf("파일 열기 실패\n");
}
for (int i = 0; i < count; i++) {
fread(&outputArray[i], size, 1, fp);
}
fread(outputArray, size, count, fp);
for (int i = 0; i < count; i++) {
printf("outputArray[%d] = %d\n", i, outputArray[i]);
}
fclose(fp);
return 0;
}
결과
outputArray[0] = 1000000
outputArray[1] = 20
outputArray[2] = 30
outputArray[3] = 40
outputArray[4] = 50
