Home C언어 (20) 파일 입출력
Post
Cancel

C언어 (20) 파일 입출력

C언어 (20) 파일 입출력

프로그램은 파일을 통해 데이터를 받거나 쓰는 경우가 많다.
이런 동작을 C언어로 해보자.

스트림(stream)

스트림(stream)이란 데이터를 입력하고 출력하기 위한 다리 같은 역할이다.
키보드, 모니터 같은 입출력 장치들은 다양한 방식으로 데이터를 주고받는다.

이 키보드와 프로그램, 프로그래뫄 모니터를 이어 주는 것이 스트림이다.
스트림에는 표준 입력 스트림인 stdin, 표준 출력 스트림인 stdout이 있다.

image

운영 체제에 의해 프로그램이 시작하면 키보드와 모니터에 대한 스트림들이 생성되고 종료되면 소멸시킨다.
이렇게 스트림을 사용하면 입출력 장치에 상관없이 동일한 함수를 사용해 프로그램을 만들 수 있다.

image

키보드와 모니터만 입력 파일, 출력 파일로 바꿔주면 파일에서 입출력을 하는 프로그램이 된다.
스트림은 모든 입력과 출력을 바이트들의 흐름으로 생각하기에 이런 동작을 가능하게 한다.

image

이렇게 표준 입력 스트림으로 입력된 값이 버퍼를 활용해 저장되고, 출력이 되는 것이다.

파일

파일 입출력은 왜 필요할까?

프로그램의 변수는 메모리에 생성되는데 메모리는 영구적인 기억 장치가 아니다.
프로그램이 종료되면 프로그램 안의 데이터가 사라지고, 전원이 꺼지면 메모리의 데이터가 사라진다.
그렇기에 데이터를 영구적으로 보관하려면 디스크 같은 보조 기억 장치에 데이터를 보관해야 한다.

파일은 프로그램이 디스크에 데이터를 기록하는 단위로 text 파일과 binary 파일이 있다.
text 파일은 우리가 쓰는 C언어 코드 같은 사람이 읽을 수 있는 텍스트가 들어 있는 파일이다.
binary 파일은 0과 1로 되어있는 컴퓨터가 읽을 수 있는 실행 파일, 이미지 파일 등이다.

파일 입출력

파일 입출력 과정은 4가지 과정으로 나눌 수 있다.

파일 스트림 생성 -> 파일 열기 -> 파일 입출력 -> 파일 닫기

여태까지 키보드와 모니터에 대한 스트림을 생각하면서 프로그램을 만들어 주지는 않았다.
왜냐하면 운영체제가 알아서 각각 stdin, stdout으로 생성해주기 때문이다.
우리는 파일을 통해서 입력과 출력을 할 것이기 때문에 파일 스트림을 생성하고 파일과 이어줘야 한다.

fopen()

fopen() 함수는 파일 경로와 열기 모드를 인자로 받아 파일 스트림을 생성하고 파일을 연다.
이 때 파일 스트림은 FILE 구조체 포인터를 의미한다.

FILE 구조체는 파일에 대한 내부 정보를 관리한다.
이 구조체를 직접 다룰 필요는 없고, 다른 함수들을 통해 이용할 수 있다.
FILE 구조체 포인터를 통해서 파일에 접근할 수 있다는 것만 알아두고 넘어가자.

1
2
3
4
5
6
7
8
9
10
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	FILE* fp;
	fp = fopen("text.txt", "w");
	if (fp == NULL) {
		printf("파일 열기 오류");
	}
	return 0;
}

text.txt의 파일 스트림을 FILE 포인터 fp에 할당한다.
이 때 fopen()이 실패하면 NULL 포인터가 반환되므로 실패 여부를 확인할 수 있다.

파일의 경로는 절대 경로 “C:\Users\source\hello\Project3\text.txt” 이렇게 전부 적어도 되고
같은 프로젝트의 폴더에 있는 파일에 작업을 한다면 위의 코드처럼 text.txt만 적어도 된다.

fopen() 의 두 번째 인자는 파일을 열 때 어떤 모드로 열 것인지를 나타낸다.

모드설명파일이 없을 때파일이 있을 때파일 형식
"r"읽기 모드 (파일을 읽기만 가능)열 수 없음 (파일이 있어야 함)파일 열기 (파일 내용은 수정 불가)텍스트
"w"쓰기 모드 (파일을 새로 생성하거나 기존 파일을 덮어쓰기)새 파일 생성기존 파일 덮어쓰기 (내용 삭제 후 새로 작성)텍스트
"a"추가 모드 (파일에 데이터를 추가)새 파일 생성파일 끝에 데이터 추가텍스트
"r+"읽기/쓰기 모드 (파일을 읽고 수정 가능)열 수 없음 (파일이 있어야 함)파일 열기 (파일 내용 수정 가능)텍스트
"w+"쓰기/읽기 모드 (파일을 새로 생성하거나 덮어쓰기, 읽기도 가능)새 파일 생성기존 파일 덮어쓰기 (내용 삭제 후 새로 작성)텍스트
"a+"읽기/추가 모드 (파일을 읽고 추가할 수 있음)새 파일 생성파일 끝에 데이터 추가텍스트

모드는 이렇게 6가지가 있는데 read(읽기)의 r, write(쓰기)의 w, append(추가)의 a와
뒤에 +를 붙이면 읽기와 쓰기를 모두 할 수 있도록 파일을 연다.

기본적으로 파일은 텍스트 모드로 열리고, 바이너리 파일을 읽기 위해서는 ‘rb’처럼 b를 추가하면 된다.

fclose()

이렇게 파일을 열고서 다 사용하면 파일을 닫아야 한다.
사용 방법은 간단하게 fclose(fp) 처럼 괄호 안에 FILE 포인터를 주면 된다.

1
2
3
4
5
6
7
8
9
10
11
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	FILE* fp;
	fp = fopen("text.txt", "w+");
	if (fp == NULL) {
		printf("파일 열기 오류");
	}
	fclose(fp);
	return 0;
}

text.txt를 쓰기/읽기 모드로 연다. 위의 표를 보면 w+은 파일이 없으면 새로 생성한다.
그 다음 파일을 닫는다. 실행을 해보면 아무런 변화가 없는 것 같이 보인다.

image

하지만 이렇게 프로젝트의 저장 위치로 가보면 text.txt가 잘 생성되었음을 확인할 수 있다.

표준 파일 입출력 함수

표준 파일 입출력 함수로는 fgets, fputs, fscanf, fprintf 등이 있다.
fgets의 원형을 보면 fgets(char* s, int n, File* stream)이다.
FILE* stream 부분에 FILE * 변수를 넣어주면 그 파일에 대한 입출력을 할 수 있고
stdin, stdout 같은 표준 입출력 스트림을 적어주면 키보드와 모니터에 대한 입출력을 한다.

image

그림으로 보면 이런 느낌으로 표준 파일 입출력 함수는 작동한다.
다음 글에서 여러 함수들을 써보기로 하고 마지막으로 EOF에 대해 적고 끝내자.

EOF

EOF란 End Of File이라는 뜻으로 파일의 끝을 나타내는 특별한 표시이다.
프로그램은 이 표시를 통해 파일의 끝을 인식하고 읽기 과정을 멈출 수 있다.
파일의 끝까지 읽으면 EOF 값을 만나고, 이를 통해 더 이상 읽을 값이 없음을 알 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    int ch;

    if (fp == NULL) {
        printf("파일 열기 오류\n");
        return 1;
    }

    // 파일의 끝까지 문자 읽기
    while ((ch = fgetc(fp)) != EOF) {
        putchar(ch);  // 읽은 문자 출력
    }

    fclose(fp);
    return 0;
}

간단한 코드를 보자.
fgetc는 다음 글에서 다룰 것이지만, 파일에서 한 글자씩 읽는 함수라고 생각하고 넘어가자.

while ((ch = fgetc(fp)) != EOF) 이라는 구문은 fp이 가리키는 example.txt에서 한 글자씩
계속 읽어오며 ch에 저장한다. ch가 EOF일 때까지 계속 반복한다.

파일의 끝에는 EOF가 있으니까 이 코드는 파일의 끝까지 읽으면 ch에 EOF가 들어가고 종료된다.
이렇게 파일에서 데이터를 읽기 위해서는 EOF를 사용해줘야 한다.
키보드 입력으로 EOF를 주려면 ctrl+z 를 입력하면 windows 시스템이 EOF로 인식한다.


이렇게 파일을 열고 닫는 fopen(), fclose()와 EOF를 봤다.
stream을 표현하느라 그림이 많아졌지만 내용 자체는 쉽고, 파일을 여는 것도 쉽다.
이제 직접 파일에다가 이런저런 데이터를 써보자.

This post is written by PRO.