C언어 입/출력 파일 스트림

    2018-02-09 21:01:56 작성

    파일 입/출력을 하기 위해서는 다음과 같은 수행 과정이 필요합니다.

    1. 파일 스트림을 형성 : fopen 함수를 이용하여 파일스트림을 형성합니다.
    2. 파일 입출력 진행 : fputs, fgets 함수등을 이용해 파일을 읽거나 씁니다.
    3. 파일 스트림 소멸 : fclose 함수를 이용해 사용한 파일스트림을 제거합니다.

    fopen

    파일 스트림을 형성합니다.

    FILE * fopen(const char * filename, const char * mode);

    fopen 함수 호출 성공시 FILE 구조체의 포인터를 반환 실패시 NULL 포인터를 반환합니다.
    첫번째 인자는 스트림을 형성할 파일이름입니다.
    두번째 인자는 스트림의 종류로 다음의 표와 같습니다.

    파일 개방 모드
    mode 의미 파일이 있는경우 파일이 없는경우
    r 파일 읽기 정상 처리 NULL 반환
    w 파일 쓰기 이전 내용을 덮어씀 새 파일 생성
    a 파일 추가 이전 내용뒤에 추가 새 파일 생성
    r+ 파일 읽기/쓰기 정상 처리 NULL 반환
    w+ 파일 읽기/쓰기 이전 내용을 덮어씀 새 파일 생성
    a+ 파일 읽기/추가 이전 내용뒤에 추가 새 파일 생성

    파일 개방모드에서 +가 있는것은 읽기 쓰기가 동시에 가능한 모드이기 때문에 더 좋을것이라고 생각할 수 있습니다.
    그러나 이러한경우에는 읽기에서 쓰기, 쓰기에서 읽기로 작업을 변경할 때마다 메모리 버퍼를 비워줘야 하는등 불편함이 있을수 있으니 일반적인 경우 r, w, a중 하나를 선택하여 사용하는것이 좋습니다.

    파일 데이터 유형
    mode 쓰기 유형 쓰기 동작 적용 대상
    t 텍스트모드(기본값) '\n'이 시스템에 맞게 변환하여 저장 문자 데이터
    b 바이너리 모드 아무런 변화없이 이진데이터 저장 동영상, 음악, 그림등

    '\n'은 C언어에서 개행을 의미하는 것이고 시스템에 따라 개행은 다른 문자로 쓰입니다.

    • MS-DOS(Windows) 파일 내 개행 : \r\n
    • Mackintosh 파일 내 개행 : \r
    • Unix 계열 파일 내 개행 : \n

    각 시스템마다 개행을 의미하는 문자가 다르므로 텍스트모드에서는 '\n'을 각 시스템에 맞는 문자로 변환하여 읽거나 쓰게 됩니다.

    fopen 함수사용시 파일스트림을 정상적으로 형성했다면 FILE 구조체 포인터를 반환받게 됩니다.
    이 포인터를 가지고 파일 스트림을 이용해 입출력을 하면 되기 때문에 FILE구조체가 어떻게 정의 되어 있는지는 알 필요가 없습니다.
    다음은 fopen 함수의 사용 예입니다.

    FILE * fp1, *fp2;
    fp1 = fopen("data.txt", "wt");
    fp2 = fopen("d:\\source/mydata.bin", "rb");

    fp1은 상대주소로 현제 실행파일위치의 data.txt 파일을 텍스트 쓰기 모드로 열었습니다.
    fp2는 절대주소로 d:\source\mydata.bin 파일을 바이너리 읽기 모드로 열었습니다.
    폴더 구분은 "\\" 하거나 "/" 로 합니다.


    fclose

    파일 스트림을 소멸합니다.

    int fclose(FILE * stream);

    fopen 함수로 파일스트림을 형성하였다면, 반드시 fclose 함수를 호출하여 파일스트림을 소멸해야 합니다.
    스트림을 소멸해야 하는 이유는 다음과 같습니다.

    • 운영체제가 할당한 자원을 반환
    • 버퍼링 되었던 데이터의 출력하여 안전하게 파일을 저장

    fclose 함수를 호출하여 스트림을 소멸하면 버퍼에 남아있는 데이터를 저장하게 됩니다.
    스트림을 소멸하지 않고 출력버퍼에 남아 있는 데이터를 비우려면 fflush 함수를 사용하면 됩니다.


    간단한 텍스트파일 입출력

    다음은 간단하게 텍스트 파일을 만들어 저장하는 예제입니다.
    프로그램 실행전 폴더가 생성되어 있어야 합니다.
    예제와 같이 하려면 C:/sample 폴더가 있어야 합니다.

    #include <stdio.h>
    
    int main(void) {
    	FILE * fp = fopen("c:/sample/ezcode.txt", "wt");
    	if (fp == NULL) {
    		puts("파일 쓰기 실패");
    		return -1;
    	}
    	fputs("이지코드\n", fp);
    	fputc('A', fp);
    	fputc('B', fp);
    	fputc('C', fp);
    	fclose(fp); // 스트림 소멸
    	printf("파일을 저장하였습니다.\n");
    	return 0;
    }


    파일을 열지 못하였다면 더이상 진행되지 않도록 프로그램을 종료 해야 합니다.
    정상저장되었다면 메모장에서 열어보면 다음과 같이 텍스트 파일이 저장된것을 확인할 수 있습니다.

    다음은 위에 저장된 파일을 읽어 출력하는 예제입니다.

    #include <stdio.h>
    
    int main(void) {
    	int ch, i;
    	char str[30];
    	FILE * fp = fopen("c:/sample/ezcode.txt", "rt");
    	if (fp == NULL) {
    		puts("파일 읽기 실패");
    		return -1;
    	}
    	fgets(str, sizeof(str), fp);
    	printf("%s", str);
    	while (1) {
    		ch = fgetc(fp);
    		if (ch == EOF) {
    			break;
    		}
    		printf("%c\n", ch);
    	}
    	fclose(fp); // 스트림 소멸
    	return 0;
    }


    fgets 함수는 개행까지 한줄을 읽어들입니다.
    반복문에서는 파일의 끝까지 한문자씩 읽어 출력합니다.