바위 뚫는중

[C] C언어 파일과 스트림, 파일의 입출력 본문

카테고리 없음

[C] C언어 파일과 스트림, 파일의 입출력

devran 2023. 3. 27. 13:40
반응형

컴퓨터 구조 수업의 프로젝트 일환으로, C언어 관련 공부를 다시 진행중..

 

[C] C언어 파일과 스트림, 파일의 입출력

스트림과 데이터의 이동

입력과 출력

데이터의 입출력은 프로그램의 흐름

쉽게 말하면, 프로그램 안으로 흘러 들어오는 것은 입력, 밖으로 흘러 나가는 것은 출력이다.

입출력의 대상은 매우 넓다. 파일의 입력, 키보드 등이 입력의 대상이 될수도 있고, 모니터와 파일이 출력의 대상이 될수도 있다. 이 말고도 프린터, 카메라 등 기타 장치도 입출력의 대상이 될 수 있다.

스트림 Stream: 데이터의 이동 수단

프로그램 상에서 모니터와 키보드를 대상으로 데이터를 입출력하기 위해서는 이들을 연결시켜주는 다리가 필요하고, 이를 ‘Stream 스트림’ 이라 한다.

실행중인 프로그램과 모니터를 연결시키는 출력스트림 (printf)

실행중인 프로그램과 키보드를 연결시키는 입력스트림 (scanf)

이러한 스트림은 운영체제에서 제공하는 소프트웨어적인(소프트웨어로 구현되어 있는) 가상의 다리이다.

스트림의 생성과 소멸

콘솔(키보드와 모니터 등)입출력과 파일입출력 사이에는 차이점이 하나있다.

파일과의 연결을 위한 스트림의 생성은 우리가 직접 요구해야 하지만, 콘솔과의 연결을 위한 스트림의 생성은 요구할 필요가 없다는 것.

즉, 콘솔 입출력의 경우에는 입력스트림과 출력스트림은 프로그램이 실행되면 자동으로 생성되고, 종료되면 자동으로 소멸되는 스트림이다. → 이 둘은 기본적으로 제공되는 standard stream 표준스트림이다.

표준스트림에는 에러 스트림도 존재하고, 각각 다음과 같은 이름이 있다,.

  • stdin 표준 입력 스트림 : 키보드 대상으로 입력
  • stdout 표준 출력 스트림 : 모니터 대상으로 출력
  • stderr 표준 에러 스트림 : 모니터 대상으로 출력

파일과 스트림

파일에 저장된 데이터를 참조

프로그램에서 파일에 저장된 데이터를 읽고 싶을때, 프로그램과 파일 사이에 스트림을 형성해야 데이터를 주고 받을 수 있음. 스트림이란 운영체제에 의해서 형성되는 소프트웨어임.

파일은 운영체제에 의해 그 구조가 결정되고 관리되는 대상이기에, 파일 뿐만 아니라 스트림의 형성도 운영체제의 몫임을 기억해야 함!!

fopen 함수호출을 통한 파일과의 스트림 형성과 FILE구조체

위와 같은 스트림을 형성하기 위해 호출하는 함수는 다음과 같음

#include<stdio.h>
FILE *fopen(const char *filename, const char *mode);

위 함수를 살펴보자

  • 첫번째 인자로는 스트림을 형성할 파일의 이름
  • 두번째 인자로는 형성할 스트림의 종류에 대한 정보를 문자열의 형태로 전달

그러면 함수는 해당 파일과의 스트림을 형성하고 스트림의 정보를 FILE 구조체 변수에 담아서 그 변수의 주소값을 반환한다!

FILE 구조체가 어떻게 정의되어 있는지는 알 필요가 없다. 우리는 FILE 구조체 변수의 멤버에 직접 접근할 일이 없기 때문이고, 위 함수가 반환하는 FILE 구조체의 포인터는 파일을 가리키기 위한 용도로 사용되어서 포인터를 이용하여 파일에 데이터를 저장하거나 파일에 저장된 데이터를 읽게된다. 따라서 FILE 구조체가 어떻게 정의되어있는지는 알 필요가 없다.

  • fopen 함수가 호출되면 FILE 구조체 변수가 생성
  • 생성된 FILE 구조체 변수에는 파일에 대한 정보가 담김
  • FILE 구조체의 포인터는 사실상 파일을 가리키는 ‘지시자’의 역할을 함

파일 입력 스트림과 출력 스트림의 생성

fopen 함수를 호출할 때는 다음 두가지가 인자로 전달되어야 한다.

  • 첫 번째 전달인자: 스트림을 형성할 파일의 이름
  • 두 번째 전달인자: 형성하고자 하는 스트림의 종류

출력 스트림의 형성을 요청하는 fopen 함수의 호출문 예시는 다음과 같다.

FILE *fp = fopen("data.txt, "wt");

코드가 의미하는 것은 파일 data.txt와 “wt”모드로 스트림을 형성하라는 뜻이다.

(wt mode: 텍스트 데이터를 쓰기 위한 출력 스트림을 뜻함. 쓸 수는 있어도 읽을 수는 없음.)

데이터를 읽기 원한다면 “rt” 모드로 입력스트림을 형성해주면 됨.

파일 데이터 쓰기

그렇다면, wt 모드로 출력스트림을 형성하여 파일에 데이터를 써보자.

#include <stdio.h>

int main(void)
{
	FILE *fp = fopen("data.txt", "wt");
    if(fp==NULL){
        puts("파일오픈실패;;");
        return -1;
    }

    fputc('A', fp); //fp가 지칭하는 파일 data.txt에 문자 A 저장
    fputc('B', fp);
    fputc('C', fp); 
    fclose(fp); //스트림 종료해주기
    return 0;
}

data.txt 파일을 확인시, 문자 데이터가 저장된 것을 확인 가능하다.

스트림 소멸을 위한 fclose

fopen이 파일을 개방한다면, fclose는 파일을 닫는다.

= fopen은 스트림 형성, fclose는 스트림 소멸

개방한 파일을 닫아줘야 하는 이유는?

  • 운영체제가 할당한 자원의 반환
  • 버퍼링 되었던 데이터의 출력

운영체제는 스트림의 형성을 위해 시스템의 자원(보통 메모리)를 할당하기 때문에, 파일을 닫아주지 않으면 할당한 채로 남아있게 되어 자원손실을 초래하기 떄문에 파일 사용 즉시 fclose 함수를 호출하여 자원을 반환해줄 필요가있음.

파일 데이터 읽기

char을 읽는다는 가정하에 변수ch에 문자가 하나씩 저장되어 반환되는 형식으로 앞서 써둔 파일 데이터를 읽어보자 (”rt” mode: 읽기만 가능)

#include <stdio.h>

int main(void)
{   
    int ch, i;
	FILE *fp = fopen("data.txt", "rt");
    if(fp==NULL){
        puts("파일오픈실패;;");
        return -1;
    }

    for(i=0; i<3; i++){
        ch =fgetc(fp);
        printf("%c \\n",ch);
    }

    fclose(fp);
    return 0;
}

파일의 개방모드(Mode)

파일 스트림은 크게 4가지로 구분가능

  • 데이터 READ 스트림 : 읽기만 가능
  • 데이터 WRITE 스트림 : 쓰기만 가능
  • 데이터 APPEND 스트림 : 쓰되, 덧붙이기만 가능
  • 데이터 READ/WRITE 스트림 : 읽기, 쓰기 모두 가능

C언어는 6가지 스트림으로 이를 세분화함

  • r 모드 / 읽기 가능 / 파일 없을 시 에러
  • w 모드 / 쓰기 가능 / 파일 없을 시 생성
  • a 모드 / 파일의 끝에 덧붙여 쓰기 가능 / 파일 없을 시 생성
  • r+ 모드 / 읽기, 쓰기 가능 / 파일 없을 시 에러
  • w+ 모드 / 읽기, 쓰기 가능 / 파일 없을 시 생성
  • a+ 모드 / 읽기, 덧붙여쓰기 가능 / 파일 없을 시 생성

다만, ‘+’ 모드에서는 읽기 → 쓰기, 쓰기 → 읽기로 변환할 때 마다 메모리 버퍼를 비워줘야 하는 불편함이 있어서 그냥 r,w,a 중에 하나를 선택하여 쓰는게 낫다

참고자료

윤성우의 열혈 C 프로그래밍

 

#파일스트림 #파일데이터읽기 #파일데이터쓰기 #C언어스트림 #C언어파일개방모드

반응형