[C] 파일 입출력 1
C언어에서 파일을 조작하는 기초적인 방법
구조체 FILE
우리가 입력한 데이터를 보관하려면 파일을 생성해야한다.
그런데 그렇게 하려면 구조체를 생성해야하는데, 파일에 대한 구조체는 이미
stdio.h 라는 라이브러리에 생성이 완료되어있다!
그러면 우리는 어떻게 하면 되느냐?
이 구조체를 포인터로 호출하면 된다. 아래 코드와 같이.</br>
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp;
return 0;
}
fopen함수
이제 파일을 조작하는 방법을 알아보자.
C언어에서는 fopen함수를 통해서 기본적으로 파일을 조작할 수 있다.
fopen함수는 내부적으로 FILE의 구조체 변수를 생성한 후 파일에 대한 모든 정보를 저장하는 역할을 한다.
그 후, 파일에 대한 구조체 변수의 주소를 리턴한다.
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp;
fp = fopen("pigs.txt", "r"); // r : 읽기모드, w : 쓰기모드, a : 추가모드
fclose(fp);
return 0;
}
fopen함수는 위와 같이 작성할 수 있다. (fopen(“경로 + 파일이름 + 파일형식”, “모드”);)
그리고 fp와 같이 포인터 변수에 지정을 해주어 파일 조작이 용이하도록 만들어준다.
절대경로 혹은 상대경로를 작성한 후 파일이름 + 파일형식을 큰 따옴표 안에 작성하고, 모드를 옆에 작성한다.
- r : 읽기모드
- w : 쓰기모드
- a : 추가모드
그리고 fclose는 파일을 닫는 역할, 포인터 변수에 대해서 지정을 해제하는 역할을 한다. (메모리 관리를 위해)
fgetc 함수
파일에서 문자를 차례로 읽어오는 역할을 하는 함수이다.
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp; // FILE 포인터 선언(주소를 저장하는 변수 : 64비트 기준 무조건 8바이트)
char ch;
fp = fopen("pigs.txt", "r"); // r : 읽기모드, w : 쓰기모드, a : 추가모드
ch = fgetc(fp); // 특정 파일에 대해서 처음 한 글자를 읽어오고 다음 글자로 넘어간다.
printf("%c\n", ch); // 결과 : T
ch = fgetc(fp); // 다음 글자를 읽어온다.
printf("%c\n", ch); // 결과 : h
fclose(fp);
return 0;
}
fgets()함수 같은 경우는 한 글자씩 읽어서 저장하는 역할을 한다.
위의 예시에서는 문자 변수로 선언된 ch에 저장하고 출력하는 모습을 보인다.
그러면 이 작업을 파일 끝까지 반복하려면 어떻게 하면 될까?
while((ch = fgetc(fp)) != -1) {
printf("%c", ch);
}
파일의 끝에는 항상 -1이 저장되어있다.
따라서, 문자로 이루어진 파일의 끝을 나타내는 문자인 -1을 만나면 함수를 끝내고, 그렇지 않으면 계속 읽어와서 저장 후 출력하는 과정을 반복시키면 된다.
사실, -1이 파일의 끝을 나타내는 이유가 stdio.h 속에 파일의 끝을 나타내는 매크로 상수가 아래와 같이 정의되어 있기 때문이다.
#define EOF -1 // end of file
따라서, -1보다는 EOF를 쓰는 것이 더 알맞을 것이다.
while((ch = fgetc(fp)) != EOF) {
printf("%c", ch);
}
파일이 없을 경우
만약에 읽고자하는 파일이 없는 경우, 오류가 발생한다.
이때, FILE구조체 생성을 실패했다고 할 수 있으며,
if (fp == NULL) {
printf("\n\n FILE open fail \n");
exit(1);
}
파일을 오픈하는 것을 실패했을 때에는
fp == NULL 임을 이용해서 프로그램을 강제종료 시킬 수 있다.
이렇게 하면 프로그램이 강제 down 되는 것을 막을 수 있다.
파일 입출력을 하기 위한 기본적 코드 정리
#include <stdio.h>
#include <stdlib.h>
int main () {
FILE *fp;
fp = fopen("파일이름.파일형식", "모드");
if (fp == NULL) {
printf("실패\n");
exit(1);
}
// 조작 코드
fclose(fp);
return 0;
}