fopen 함수호출을 통한 파일과의 스트림 형성과 FILE 구조체
다음은 스트림을 형성할 때 호출하는 함수이다.
이 함수의 호출을 통해서 프로그램상에서 파일과의 스트림을 형성 할 수 있다.
#include <stdio.h> FILE *fopen(const char *filename, const char *mode);
-> 성공 시 해당 파일의 FILE구조체 변수의 주소 값, 실패시 NULL 포인터 반환 |
|
위 그림은 프로그램상에서 fopen 함수를 호출 했을 때 일어난 일들을 정리해 놓은 것이다.
위 그림에서 주목할 부분은 다음 세가지 이다.
1. fopen 함수가 호출되면 FILE 구조체 변수가 생성된다.
2. 생성된 FILE 구조체 변수에는 파일에 대한 정보가 담긴다.
3. FILE 구조체의 포인터는 사실상 파일을 가리키는 '지시자'의 역할을 한다.
입력 스트림과 출력 스트림의 생성
fopen 함수를 호출할 때에는 다음 두가지가 인자로 전달 되어야 한다.
1. 첫 번째 인자 스트림을 형성할 파일의 이름
2. 두 번째 인자 형성하고자 하는 스트림의 종류
스트림의 소멸을 요청하는 fclose 함수
간단히 설명하면 fclose함수는 fopen 함수의 반대 기능을 제공한다.
fopen 함수가 스트림을 형성하는 함수라면, fclose 함수는 스트림을 해제하는 함수이다.
다시 말해서 fopen 함수가 파일을 개방하는 함수라면, fclose 함수는 파일을 닫는 함수이다.
#include <stdio.h> int fclose(FILE *stream);
-> 성공 시 0, 실패 시 EOF를 반환 |
fclose 함수의 호출을 통해서 개방되었던 파일을 닫아줘야 하는 이유는?
1. 운영체제가 할당한 자원의 반환
2. 버퍼링 되었던 데이터의 출력
fflush 함수
스트림dmf 종료하지 않고 버퍼만 비우고 싶을 때에는 fflush 함수를 호출하면 된다.
#include <stdio.h> int fflush(FILE *stream);
-> 함수호출 성공 시 0, 실패 시 EOF 반환 |
파일의 개방 모드(Mode)
형성할 수 있는 스트림의 종류는 다양하다.
기본적으로 다음 두 가지 기준을 통해서 스트림을 구분하게 된다.
기준 1 : 읽기 위한 스트림이냐? 쓰기 위한 스트림이냐?
기준 2 : 텍스트 데이터를 위한 스트림이냐? 바이너리 데이터를 위한 스트림이냐?
기준 1. 읽기 위한 스트림이냐 쓰기위한 스트림이냐
데이터의 이동방향을 기준으로 다음과 같이 네가지로 구분할 수 있다.
1. 데이터 READ 스트림 - 읽기만 가능
2. 데이터 WRITE 스트림 - 쓰기만 가능
3. 데이터 APPEND 스트림 - 쓰되 덧붙여 쓰기만 가능
4. 데이터 READ/WRITE 스트림 - 읽기, 쓰기 모두 가능
그러나 C언어는 이를 총 6가지로 스트림을 세분화 한다.
|
위 표를 참조하여 필요로 하는 스트림의 특성과 일치하는 '파일의 개방 모드(mode)'를 선택하면 된다.
그리고 웬만하면 r,w,a 중에서 선택해서 쓰자.
텍스트 파일과 바이너리 파일
텍스트 파일 : 사람이 인식할 수 있는 문자를 담고 있는 파일
바이너리 파일 : 텍스트 파일 이외에 컴퓨터가 인식할 수 있는 데이터를 담고 있는 파일
데이터의 입출력을 위해서 스트림을 형성할 때 이와 관련해서 특별히 신경 쓸 부분은 문장의 끝을 의미하는 개행의 표현방식이다.
개행에 대해 알아보자
우리가 쓰는 C언어에서 개행은 \n이다. 하지만 이는 C언어만의 약속이다.
다른 환경에서 표시되는 개행을 살펴보면
MS-DOS(Windows)의 파일 내 개행 - \r\n
Mac(Mackintosh)의 파일 내 개행 - \r
Unix 계열의 파일 내 개행 - \n
서로 다른 표시방법일 경우에 개행의 표현 형태 변환을 직접 하려니 귀찮다는 생각이 들지 않을 수 없다!
그렇다면 파일을 텍스트 모드로 개방하면 된다.
이 경우 형태의 변환이 자동으로 이뤄진다.
"C 프로그램에서 \n을 파일에 저장하면 \r\n으로 변환되어 저장됨"
"파일에 저장된 \r\n을 C 프로그램상에서 읽으면 \n으로 변환되어 읽어짐"
따라서 우리가 직접 개행 문자의 변환을 신경 쓸 필요가 없다.
그저 텍스트 모드로 파일을 개방하면 된다는 이야기다.
기준 2. 텍스트 모드와 바이너리 모드
텍스트 모드의 파일 개방을 위해서는 fopen 함수의 두 번째 인자로 다음 중 하나를 전달해야 한다.
rt, wt, at, r+t, w+t, a+t
이는 파일 개방모드에 텍스트 모드를 의미하는 t가 붙은 형태이다.
반대로 바이너리 데이터를 저장하고 있는 파일의 경우에는 이러한 형태의 변환이 일어나면 안되기 때문에(아무런 변환도 일어나면 안되기 때문에) 바이너리 모드로 파일을 개방해야 한다.
그리고 이를 위해서는 fopen 함수의 두 번째인자로 다음중 하나를 전달해야 한다.
rb, wb, ab, r+b, w+b, a+b
이 역시 파일 개방모드에 바이너리 모드를 의미하는 b가 붙은 형태이다.
참고로 개방모드에 t도 b도 붙여주지 않으면 파일은 텍스트 모드로 개방된다는 사실도 잊지 말자.
파일 입출력 함수의 기본
feof 함수
- 파일의 끝을 확인하는 하는 경우에 유용하게 사용.
#include <stdio.h> int feof(FILE *stream);
->파일의 끝에 도달한 경우 0이 아닌 값 반환 |
바이너리 데이터의 입출력 : fread, fwrite
#include <stdio.h> size_t fread(void *buffer, size_t size, size_t count, FILE * stream);
->성공 시 전달인자 count, 실패 또는 파일의 끝 도달 시 count보다 작은 값 반환
예를 들어 int buf[12]; fread((void*)buf, sizeof(int), 12, fp); //fp는 FILE 구조체 포인터 "sizeof(int)크기의 데이터 12개를 fp로부터 읽어 들여서 배열 buf에 저장하라!"라는 의미로 해석된다.
|
#include <stdio.h> size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream);
->성공 시 전달인자 count, 실패 시 count보다 작은 값 반환
예를 들어 int buf[7]={1, 2, 3, 4, 5, 6, 7}; fwrite((void*)buf, sizeof(int), 7, fp); "sizeof(int) 크기의 데이터 7개를 buf로 부터 읽어서 fp에 저장해라!"라는 의미로 해석된다. |
서식에 따른 데이터 입출력 : fprintf, fscanf
임의 접근을 위한 '파일 위치 지시자'의 이동
파일 위치 지시자의 이동: fseek
#include <stdio.h> int fseek(FILE * stream, long offset, int wherefrom);
->성공 시 0, 실패 시 0이 아닌 값을 반환 |
현재 파일 위치 지시자의 위치는 : ftell
#include <stdio.h> long ftell(FILE * stream);
->파일 위치 지시자의 위치 정보 반환 |
- 윤성우 저, 열혈강의 C프로그래밍 中 -
'Programming Study > C' 카테고리의 다른 글
매크로와 선행처리기 (1) | 2014.09.05 |
---|---|
메모리 관리와 메모리 할당 (0) | 2014.09.05 |
구조체와 사용자 정의 자료형_2 (0) | 2014.09.04 |
구조체와 사용자 정의 자료형_1 (0) | 2014.09.04 |
문자와 문자열 관련 함수 (0) | 2014.09.04 |