<개인공부>/[C언어, C++]

[C언어/C++] 파일 입출력 fopen, fclose 함수에 대해서

사용자 BlockDMask 2020. 6. 12. 00:43
반응형

안녕하세요. BlockDMask 입니다.

오늘은 파일을 열고 닫고 저장하고 할 수있는, 파일을 다룰수 있는 파일 입출력 함수에 대해서 알아보려고 합니다.

즉 C/C++에서 파일 입출력을 할 수 있게 하는 함수 fopen, fclose 에 대해서 알아보려고 합니다.

fopen, fclose 함수의 원리나 동작 방식에 대해서 깊게 들어가자면 글이 너무 길어질것 같아서 최대한 간단하게 요약해서 적어보려고 합니다.


<목차>

1.fopen,fclose 함수 원형과 매개변수들의 사용법

2.파일 입출력함수 fopen, fclose 간단 사용법과 예제. 
    1) 파일이 존재하지 않을때 파일을 만드는 만들어서 쓰는법

    2) 파일이 존재할때 덮어씌워지는 경우?

    3) 파일의 문자열을 읽어오는 방법

    4) 파일의 끝에 문자열을 넣는 방법


C++ 파일 입출력(ofstream, ifstream)에 대해서 알고싶다면 [바로가기]


1.fopen,fclose 함수 원형과 매개변수들의 사용법


 fopen, fclose 함수의 헤더파일


C언어 : <stdio.h>

C++ : <cstdio>



 fopen 함수 원형


FILE* fopen (const char* fileName, const char* fileMode)


함수의 이름을 보면 f + open 인데요. 

f는 file을 말합니다. 즉 file open, “파일을 열어라”라는 함수 입니다. 명확한 이름이죠?


첫번째 매개변수 : fileName = 파일의 이름 (경로 포함)

두번째 매개변수 : fileMode = 파일을 어떤식으로 오픈할건지, 읽기만 할건지 쓰기만 할건지 둘다할건지.

반환 형 : 해당 파일을 가리키는 파일 포인터


파일의 경로를 포함한 이름을 첫번째 매개변수로 받고, 그 파일을 어떤 모드로 오픈할건지 결정해서 오픈을 하고

해당 파일을 가리키는 포인터를 반환하는 함수 입니다.

우리는 이 포인터를 가지고 파일에 접근해서 파일의 내용을 읽거나, 내용에 뭔가를 추가 혹은 삭제하는 작업을 진행할 수 있습니다.


첫번째 인자파일 이름은 그렇다 치고, 두번째 인자에 대해서 설명을 조금더 해야할것 같습니다. 

C언어, C++ 에서 이 함수를 만든 사람이 이미 fileMode에 들어갈 인자들을 정해 놓았는데요. 우리는 그걸알아야 합니다.


두번째 인자는 아래와 같은 파일을 오픈할 방식을 정할 수 있습니다.

"r" : read mode. 파일이 존재하면 해당 파일을 열겠다. 읽기 전용으로 열것이다. 그러므로 편집은 못한다. 파일이 존재하지않으면 에러반환.

“w” : write mode. 파일이 존재하면 해당 파일을 열겠다. 하지만 안에 무슨 내용이 있던 열어서 편집할것 이고 새로 붙여넣기 할것이다. 만약 파일이 존재하지 않으면 새로 만들것이다.

“a” : append mode. 파일이 존재하면 해당 파일을 열겠다. 안에 내용이 있으면 맨 뒤에서 부터 편집해서 넣을것이다. 만약 파일이 존재하지 않으면 새로 만들것이다.

“r+”  : read+ mode. 파일이 존재하면 해당 파일을 읽고 쓰기 둘다 가능하게 열겠다. 파일이 존재하지 않으면 에러를 반환한다.

“w+” : write+ mode. 파일이 존재하면 해당 파일을 읽고 쓰기 둘다 가능하게 열겠다. 파일이 존재하지 않으면 새로 만들겠다.

“a+” : append+ mode. 파일이 존재하면 해당 파일의 끝에서 부터 읽고 쓰기가 둘다 가능하도록 열겠다. 파일이 존재하지 않으면 새로 만들겠다.


이미 있는 파일을 편집만 하고 싶다면 append 모드로 열어서 맨 뒤에 부터 편집하면될것이고

아예 파일이 없는걸 생성하거나, 파일 내용을 싸그리 바꾸고 싶다면 write 모드로 열어서 덮어 씌우면 됩니다.

파일을 읽기만 할거라면 read 모드로 해서 열면 됩니다.


*여기서 좀더 들어가보자면 

r, w, a, r+, w+, a+ 옵션 이외에. 

텍스트 모드로 열지 바이너리 모드로 열지 rt, wt, at 텍스트 모드, rb, wb, ab 바이너리모드 이렇게 옵션을 추가할 수도 있습니다.

기본적으로 아무것도 입력하지 않으면 텍스트 모드로 파일에 접근하게 됩니다.




▶ fclose 함수 원형


int fclose (FILE* filePointer)


fclose 함수는 filePointer 를 매개변수로 받습니다. 

즉 fopen으로 열때 반환형으로 받은 파일포인터를 fclose의 매개변수로 넣으면 열었던 파일을 닫을 수 있습니다.


fclose의 반환형은 int 인데 정상적으로 파일을 닫았을 땐 0을 반환하고 그렇지 않을땐 EOF (-1)을 반환합니다.


*EOF란? end of file의 약자로서 C언어에서 #define을 이용해서 -1 을 EOF라 명명하여 사용합니다. 

 파일의 마지막을 알리기 위해서 -1 반환하려고 약속을 하는데 -1  그대로 반환하면 헷갈리니까 EOF 라는 이름을 붙여서 사용하는것 입니다.


2. 파일 입출력함수 fopen, fclose 좀더 자세히 알아보자


(1) 파일이 존재하지 않을때 파일을 만들어서 쓰는 방법


파일이 존재하지 않을때 "w"모드로 파일을 열고, printf가 아닌 fprintf를 이용해서 파일에 문자열을 작성해보겠습니다.


1
2
3
4
5
6
7
8
#include<stdio.h>
int main(void)
{
    FILE* pFile = fopen("test.txt""w"); //write mode
    fprintf(pFile, "blockdmask");        //printf -> fprintf
    fclose(pFile);
    return 0;
}
cs


파일이 없는 경우 -> 새롭게 test.txt 파일이 생성되고, “blockdmask” 라는 문장이 삽입됩니다.







(2) 파일이 존재할때 다시 w 모드로 하면 어떤식으로 될까?


위 예제를 실행하고 파일이 생긴 후에 파일에 넣을 내용을 살짝 바꿔서 다시 실행해 볼까요?

이번에도 마찬가지로 "w" 모드로 파일을 열어서 fprintf 함수를 이용해서 파일에 문자열을 넣어봤습니다.

이미 파일이 존재하는 경우에 어떤식으로 동작을 하게 될까요?


1
2
3
4
5
6
7
8
#include<stdio.h>
int main(void)
{
    FILE* pFile = fopen("test.txt""w");    //write mode
    fprintf(pFile, "this is blockdmask file read write example");
    fclose(pFile);
    return 0;
}
cs



파일이 있는 경우 -> 새롭게 test.txt 파일에 덮어씌워지고, “this is blockdmask file read write example” 라는 문장이 삽입되어있는걸 볼 수 있습니다.





(3) 이미 파일은 존재하고 그 파일을 열어서 read 모드로 사용하는방법


위에 예제를 잘 따라오셨다면 “test.txt”파일이 존재할 것 입니다. 2번째 까지 하셨다면 “this is ~~~ example” 이라는 문장이 있겠죠?

이상태에서 코드를 아래와 같이 수정해 봅시다. 파일에 있는걸 한번 읽어볼게요.

이번 코드에서 파일에 존재하는 문자열을 읽어올 함수는 fgets 함수입니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h>
int main(void)
{
    FILE* pFile = fopen("test.txt""r"); //read mode 
    if(pFile == NULL)
    {
        //r로 읽을 때는 파일이 없을 수 있기 때문에 이렇게 널체크를 해주어야합니다.
        //파일이 없으면 FILE*가 NULL 입니다.
        //파일이 없을때 파일을 만드는 처리를 하던지 프로그램에 맞게 짜면됩니다.
        //여기서는 프로그램을 종료 하겠습니다.
        printf("파일이 없습니다. 프로그램을 종료합니다.");
        return 0;
    }
    
    //여기까지 와다는건 read 모드로 파일이 열린것 입니다.
    char str[50];
    fgets(str, 50, pFile);  //파일에 있는거 읽어오기
    
    fclose(pFile);          //파일 닫기
    printf("%s\n", str);    //터미널에 출력
    return 0;
}
cs


요로케 잘 읽히는것을 볼 수 있습니다.






(4) 이미 파일은 존재하고 그 파일의 끝에서 부터 편집 하는 방법


1,2 번 예제를 통해서 이미 test.txt 파일에 특정 문자가 들어가있죠? 그 상태에서 이 예제를 작성해볼게요.

이번엔 파일을 append mode를 이용해서 열어서 파일의 맨끝에 fputs 함수를 이용해서 문자열을 넣어보겠습니다.


1
2
3
4
5
6
7
8
#include<stdio.h>
int main(void)
{
    FILE* pFile = fopen("test.txt""a");   // file open. append mode.
    fputs("\nc 언어 file append test. by blockdmask.", pFile);    //fputs를 이용해 파일에 쓰기
    fclose(pFile);                          // file close.
    return 0;
}
cs


이렇게 append mode 로하면 바로 파일 포인터가 파일의 맨 끝을 가리키기 때문에, 파일 끝에 무언가를 바로 추가할때 유용합니다.





*정보 & 굴팁. 

파일로부터 내용을 읽는다거나 파일에 무언가를 쓸때는

우리가 알고있는 기본함수들의 맨 앞에 f 를 붙인 함수를 생각하면 됩니다.


우리가 보통 콘솔 입출력할때는 printf, scanf, puts, gets, putc, getc 등등 를 사용하죠? 

함수 앞에 f 만 붙이면 파일에 입력과 출력을 할수 있습니다.

fprintf, fscanf, fputs, fgets, fputc, fgetc 이렇게 함수이름 앞에 f를 붙인 함수들은 맨 첫번째 인자혹은 맨뒤에 인자로 파일포인터(FILE*)를 받습니다.

그럼 예제에서 처럼 처음에 오픈한 파일 포인터를 넣고 원래 써오던 함수인것처럼 자연스럽게 사용하면 됩니다.



이상으로 C언어, C++ 파일 입출력 fopen, fclose에 대해서 알아 보았습니다.

반응형