파일 스트림 (File Stream)
프로그램 안에서 파일에 저장되어 있는 데이터를 참조하고 싶을 때 우선 파일 스트림을 형성해야 한다.
fopen
파일 스트림은 fopen 함수호출을 통해서 형성할 수 있다.
fopen 함수의 반환형과 요구하는 매개변수는 다음과 같다.
FILE* fopen(const char* filename, const char* mode);
fopen 함수는 스트림을 형성할 파일 이름과 스트림의 종류를 매개변수로 요구하며
스트림을 형성한 후 스트림과 파일의 정보를 FILE 구조체 변수에 담아서 그 변수의 주소값을 반환한다.
여기서 FILE은 기본 자료형이 아니기 때문에 구조체라는 것을 알 수 있다.
파일 개방 모드
C언어에서는 스트림의 성격에 따른 6가지의 파일 개방 모드가 존재한다.
1. r 읽기 모드
2. w 쓰기 모드
3. a 덧붙여 쓰기 모드
4. r+ 읽기/쓰기 모드
5. w+ 읽기/쓰기 모드
6. a+ 읽기/덧붙여 쓰기 모드
이때 파일이 존재하지 않으면 r과 r+의 경우에는 에러가 발생하고 나머지 경우에는 파일을 생성한다.
r+, w+, a+를 사용할 경우에는 쓰기에서 읽기, 읽기에서 쓰기로 작업을 변경할 때마다 버퍼를 비워줘야 한다.
텍스트 파일과 바이너리 파일
사람이 문자로 인식할 수 있는 데이터를 담고 있는 파일을 텍스트 파일이라 하며
그 외에 컴퓨터가 인식할 수 있는 데이터를 담고 있는 파일을 바이너리 파일이라고 한다.
영상이나 음원파일 등이 바이너리 파일에 포함된다.
텍스트 파일과 바이너리 파일의 스트림을 생성할 때에 구분이 필요하다.
파일 개방모드 뒤에 파일의 형식을 명시해 주는 형식인데
텍스트 파일은 t를 사용하고 바이너리 파일은 b를 사용한다.
따라서 텍스트 모드의 경우 rt, wt, at, r+t, w+t, a+t의 형식으로 사용할 수 있다.
r+t, w+t, a+t 에서 +는 t 뒤에 와도 상관이 없다.
파일 입출력
파일 스트림을 이용한 입력은 아래코드처럼 사용이 가능하다.
#include <stdio.h>
int main()
{
FILE* fp = fopen("test.txt", "wt");
fputc('A', fp);
fputc('B', fp);
fputc('C', fp);
return 0;
}
위 코드를 실행하면 실행파일과 같은 폴더에 텍스트파일이 생성되고 ABC라는 문자가 들어가 있는 것을 확인할 수 있다.
출력의 경우 아래 코드처럼 사용이 가능하다.
test.txt에는 미리 데이터를 넣어두었다.
#include <stdio.h>
int main()
{
char str[30];
int ch;
FILE* fp = fopen("test.txt", "rt");
ch = fgetc(fp);
printf("%c \n", ch);
ch = fgetc(fp);
printf("%c \n", ch);
fgets(str, sizeof(str), fp);
printf("%s", str);
fgets(str, sizeof(str), fp);
printf("%s", str);
return 0;
}
텍스트파일에 들어있던 데이터와 출력된 결과는 다음과 같다.
fgets 함수는 개행을 기준으로 문자열을 입력받기 때문에 위와 같은 결과값이 도출된다.
fclose
fclose는 생성한 스트림을 해제하는 함수이다.
malloc으로 메모리를 할당했을 때 free를 통해 해제하는 것과 마찬가지로 할당된 자원의 반환, 그리고 버퍼링 되었던 데이터의 출력을 위해 생성한 스트림은 닫아주어야 한다.
fclose의 형태는 아래 코드와 같다.
FILE* fp = fopen("test.txt", "wt");
int fclose(FILE* stream);
이때 함수 호출 성공 시 0을 반환하고 실패 시 EOF를 반환한다.
버퍼 비우기
fflush 함수를 사용하면 파일 스트림의 버퍼를 비울 수 있다.
fflush(fp);
그러나 앞선 포스팅에서 설명한 것처럼 fflush 함수를 사용하여 입력버퍼를 비우는 것은 불가능하다.
하지만 신경 쓸 필요는 없다.
파일에 입력된 데이터는 날아가지 않고 언제든지 읽을 수 있기 때문이다.
파일의 경로
아까 텍스트 파일이 생성될 때 실행파일과 같은 폴더에 생성되었다고 말했는데 이것은 실행환경과 설정에 따라 생성되는 위치가 달라질 수 있다.
따라서 이러한 혼란을 피하기 위해 절대경로를 포함하여 파일의 이름을 지정할 수도 있다.
FILE* fp = fopen("C:\\Users\\enchupin\\test\\test.txt", "wt");
\를 표현하기 위해서 C언어에서는 \\를 사용해야 하는 것도 잊지 말자.
'C언어 > C언어 문법' 카테고리의 다른 글
[C언어] 헤더파일, #include의 활용 (0) | 2024.02.28 |
---|---|
[C언어] 파일의 분할 (extern, static) (0) | 2024.02.28 |
[C언어] 조건부 컴파일 매크로 (#if, #elif, #endif, #ifdef, #ifndef) (0) | 2024.02.25 |
[C언어] 매크로 (define, 오브젝트 유사 매크로, 매크로 함수) (0) | 2024.02.25 |
[C언어] 구조체의 중첩 (0) | 2024.02.25 |