BOX-IT/C++

[C++] 파일 개방과 입출력

Buang 2022. 5. 16. 14:23
반응형

'[혼공C_새로워진 이것인 C언어다.] 34강-파일 개방과 입출력' 강의를 보면서

정리한 필기자료임을 미리 밝힙니다.


printf("hello");

 

라고 입력하면 hello가 출력될 것이다.

(main함수 선언이나 stdio.h가 모두 작성되어 있다고 가정하고 말이다.)

 

아무튼 hello란 문자가 출력되는 것 까진 좋은데

앞으로 이 데이터(hello)를 연산한 결과를 화면에만 띄우는 것에 그치지 않고

하드디스크로부터 가지고 올 수 있도록

해서 계속해서 활용할 수 있도록 해보자.

 

즉 파일 입출력은

하드디스크로부터 데이터를 가지고 오는 것이다.@

 


<목차>

 

1. 파일 개방

- 표준 입출력 스트림 파일

- fopen

- fgetc함수

  - 위치 지시자

  - EOF (-1)

- fputs 함수

 

2. 텍스트 파일과 바이너리 파일

3. +개방 모드, fseek, rewind, feof 함수


1. 스트림 파일과 파일 포인터

 

일단 구체적인 설명에 앞서

파일이 저장되는 과정에 대해서 살펴보고 가고자 한다.

 

메모장에 'apple'을 입력하고 난 뒤에 보면

커서가 apple 맨 뒤에서 깜빡거릴 것이다. 

 

여기서 스페이스바를 누르면 커서가 옆으로 갈 것이고

엔터키를 누르면 아래로 내려갈 것이다. 

 

신기한 점은 내가 키보드를 입력해서 문자를 입력하지 않고

그냥 스페이스바를 한 번 누르거나

엔터키를 한 번 누른 것도 파일에 데이터가 추가되는 것과 같다는 점이다.

스페이스바 한 번, 엔터키 한 번이 character가 되는 것이다. 

 

이제 ctrl+s를 눌러서 메모장의 내용을 저장하고자 한다.

ctrl+S를 누르면 메모장 파일은 HDD(하드디스크)에 저장된다.

즉 HDD에 apple이라는 5개의 문자가 저장되는 것이다.

더불어서 부수적인 정보도 함께 저장되는데

파일이 수정된 날짜, 

하드디스크의 몇 번째 블록에 저장되어 있는지같은 블록 번호,

해당 파일의 크기 등도 하드디스크에 저장된다.

 

이 부분을 염두해두고,

우리는 하드디스크에 저장되어 있는 데이터를 읽어내서

화면에 출력하는 프로그램을 만들려고 한다. 

 

 

하드디스크에 있는 데이터를 읽어서 

프로그램에 불러오려면

 

하드디스크에 함께 저장되어 있던 

데이터의 부수적인 정보(위에서 언급한 파일이 수정된 날짜, 파일의 크기 등)를 메모리에 가져와야 한다. 

 

부수적인 정보를 먼저 메모리에 가져다 놓음으로서

실제 정보(apple)이 있는 곳의 위치를 확인할 수 있고,

데이터(apple)을 읽어낼 때 몇 byte까지 읽어내야 하는지도 알 수 있다. 

 

 

여하튼,

부수적인 정보를 메인메모리에 가져왔고,

자료가 여러개라 구조체로 정의한다고 했을 때

구조체의 이름을 FILE이라고 해보겠다.

 

 stdio.h를 보면 typedef struct_ioduf를 FILE로 재정의 해서

FILE만 적어도 구조체를 만들 수 있다. 

 

 

이제 apple을 가져와야 하는데

a라는 문자 하나만 가져올 순 없고,

apple전체 한 블록을 메인메모리로 가져와야 한다. 

그래서 메인메모리에 한 데이터를 임시로 저장할 '버퍼'란 공간을 선언한다. 

버퍼의 위치는 FILE 구조체에 있는 어떤 맴버가 가리키게 만들어준다.

 

이런 구조를 만들어줘야 

FILE이란 구조체 변수에 부수적인 데이터를 가져다 놓고

apple이란 데이터를 버퍼를 통해서 읽을 수 있다.

 

FILE과 버퍼 구조를 스트림 파일(파일 입출력 위한 파일)이라고 부른다.

 

HDD디스크에 있는 데이터를 읽기 위해선

스트림 파일을 만들어줘야 읽을 수 있다.

스트림 파일을 만들어주는 함수가 있는데 fopen이란 함수다.

 

fopen 함수

파일 입출력을 위해 fopen 함수를 호출해야 한다. 

fopen함수는 내가 어떤 이름의 파일을 오픈할 건지 알려줘야 한다.

만약 apple이 저장되어 있는 파일 이름이 a.txt라면 

 

fopen("a.txt")

 

라고 할 수 있다. 

 

두 번째 인자는 개방모드다.

파일의 데이터와 함께 저장되어 있는 위치정보, 날짜 정보를 메모리 갖다놓는 준비작업이 개방이다.

개방 모드에는 3가지 종류가 있다.

 

1) read

 

내가 파일을 읽기 위해선 read mode라고 해서

 

fopne("a.txt", "r")

이라고 쓴다.

 

2) write

 

내가 프로그램에서 만든 데이터를

하드디스크에 출력하려고 한다. 

이런 경우는 쓰기 위해서이니까 write의 약자인 w를 쓴다.

 

3) append

 

내가 기존에 만들어 놓은 데이터에 무언가를 덧붙여서 기록하려고

한다면 append의 약자인 a를 쓴다.

 

 

fopen 함수 사용법과 코드

 

fopen("a.txt", "r")

 

이렇게 작성해주면 fopen은

하드디스크에 있는 a.txt란 파일의 정보를 메인 메모리의

FILE 구조체 변수 안에 가져다 놓는다. 

그럼 FILE 구조체 변수 안에 a.txt안의 데이터가

어디있고, 몇 바이트인지를 알 수 있다.

 

그런데 여기서 그냥 return을 하면

FILE 구조체 변수의 위치를 알 수가 없다. 

위치를 알아야 메모리 접근을 해서 쓸 수 있으니

FILE구조체 변수의 시작 주소값, 여기선 500이라고 했을 때 

이 주소값을 반환한다면 주소값을 저장할 변수가 필요할 것이다. 

 

포인터 변수를 선언해야 한다. (왜?)

가리키는 자료형이 FILE 구조체형 자료니까

 

FILE * fp; <<파일 구조체 변수의 주소를 저장하는 포인터 변수 선언

fp = fopen("a.txt", "r");

 

여기서 만약에 a.txt란 파일이 없는 경우를 대비해서

NULL 포인터를 반환하도록 하자. NULL은 0번지다.

 

FILE *fp; //FILE 구조체 변수 선언
fp = fopen("a.txt", "r"); //fopen 함수를 통해서 파일 개방

if (fp == NULL)
{    
    printf("파일이 없다");
    exit(1); //종료
}
fclose(fp); //정리작업

 

Q: fopen함수를 통해서 a.txt란 파일을 찾을 때 어디서 찾을까? 

하드 디스크를 전부다 뒤지면 시간이 너무 오래 걸린다. 

fopen함수는 현재 작업하고 있는 디렉토리에서만 찾는다. 

현재 작업하고 있는 디렉토리란 실행파일이 실행되고 있는 위치를 말한다.

 

 

현재 작업토리 밑에 서브 디렉토리가 있고

그 안에다가 내가 어떤 파일을 집어넣었다면

이렇게 써주면 된다.

 

sub\\a.txt

해석하자면

현재 작업 디렉토리를 기준으로

sub라는 디렉터리가 있는데 그 디렉터리 안에 있는 a.txt를 찾아라이다.

 

절대경로로 작성할 수도 있다.

 

c\\shu\\chta\\a.txt

 

이렇게 절대경로로 작성하면

현재 작업하고 있는 디렉터리가 어디는 간에 상관없이

a.txt파일을 불러올 수 있다. 

 

 

이렇게 파일 개방에 대해서 알아봤다.

다음 시간에는 파일 개방 후 입출력하는 방법에 대해서 알아보고자 한다.

 

 

 

 

반응형