C language - 3. file I/O(파일 입출력)

 파일 입력함수에는 getc(), fgetc(), fgets(), fscanf(), fwrite()가 있고 파일 출력함수에는 putc(), fputc(), fputs(), fprintf(), fread()가 있습니다.



1. 텍스트 파일 입출력

#include <stdio.h>

void main()
{
       FILE * fp1 = fopen("input.txt", "rt"); // input.txt 파일을 읽기용으로 선언
       FILE * fp2 = fopen("output.txt", "wt"); // output.txt 파일을 쓰기용으로 선언
       if(fp1 == NULL || fp2 == NULL) {
              puts("파일 오픈 실패");
              return;
       }
       char str[30];
       int ch1, ch2;

       ch1 = getc(stdin);  // steam부분에 stdin을 넣어서 표준 입력함수와 같은 효과를 보인다
       ch2 = fgetc(stdin);
       fgets(str, sizeof(str), fp1); //fp1의 내용을 읽어 들여 str크기의 str 변수에 복사

       putc(ch1, stdout);
       fputc(ch2, stdout);
       fputs(str, sizeof(str), fp2); // 문자열을 출력하지만 개행은 되지 않는다

       fclose(fp1); // fopen으로 열어준 FILE 포인터형은
       fclose(fp2); // 반드시 fclose로 닫아주어야한다

}


FILE구조체는 코드 밖의 파일에서 값을 읽어오거나 저장하기 위해 사용합니다. FILE의 포인터형으로 선언후 fopen 함수를 사용해 파일의 위치와 개방모드를 매개변수로 입력하며 개방모드는 아래의 표와 같이 사용합니다.

fopen 함수는 운영체제가 파일을 열기위해 자원을 따로 할당해주어서 사용되기때문에 성능저하를 막기위해 그리고 출력버퍼에 기다리고있던 값들을 파일에 저장하여 손실을 막아주므로 사용한뒤 반드시 끝나기전에 fclose 함수를 사용하여 닫아주어야 합니다.

getc(), fgetc(), putc(), fputc()함수의 c는 모두 char변수의 c를 약자로 쓰고있어서 문자 하나를 입출력하는 함수이고 fgets(), fputs()는 문자열을 의미하는 string의 s이며 이는 표준 입출력함수들과 비슷하며 파일입출력함수의 f는 file의 약자를 의미합니다.


2. 바이너리 파일 입출력


#include <stdio.h>

void main()
{
       FILE * fp1 = fopen("input.bin", "rb"); // 바이너리 파일 읽기용으로 선언
       FILE * fp2 = fopen("output.bin", "wb"); // 바이너리 파일 쓰기용으로 선언
       if(fp1 == NULL || fp2 == NULL) {
              puts("파일 오픈 실패");
              return;
       }
       int count;
       char str[20];

       while(1)
       {
              count = fread((void*)str, sizeof(char), (sizeof(str)/sizeof(char)), fp1); // fp1으로 파일을 읽어들여서 sizeof(str)의 크기만큼 str에 읽어들임
              if(count < (sizeof(str)/sizeof(char)))
              {
                     if(feof(fp1)!=0) // 파일이 실패했는지 확인 성공시 0이 아닌 값을 반환
                     {
                            fwrite((void*)str, sizeof(char), count, fp2);
                            puts("복사 완료");
                            break;
                     }
                     else
                            puts("복사 실패");
                     break;
              }
              fwrite((void*)str, sizeof(char), (sizeof(str)/sizeof(char)), fp2); // 참조
       }

       fclose(fp1);
       fclose(fp2);
       return;
}


처음으로 fread 함수를 실행할 때 읽어들인 바이너리 파일이 char형 변수 str보다 클 때 str의 최대 크기만큼만 읽어들인뒤 '참조'부분에서 fwrite를 실행합니다. 계속해서 while문을 왕복하면서 바이너리 파일을 쓰다가 fread에서 남은 바이너리 파일이 str보다 작으면 count에는 str보다 작은 값이 입력이 됩니다. 이 때 첫 if문에선 count의 값이 작기 때문에 내부로 가게 되는데 파일의 끝에 도달해서 내부로 왔는지 함수의 실패로 왔는지 확인하기위해 파일의 끝에 도달했을시 0이 아닌값을 반환하는 feof함수를 써서 확인후 남은 크기의 값을 바이너리파일에 마지막으로 쓴다음 while문을 나옵니다