..

Search

46) 파일 입출력 함수

46) 파일 입출력 함수

파일 입출력 함수


파일 입출력 함수

C언어에서 인수를 하나만 전달받는 대부분의 입출력 함수는 스트림이 stdin이나 stdout으로 고정되어 있는 함수입니다.

하지만 입출력 함수 중에서 이름이 f로 시작되는 함수는 입출력 스트림을 사용자가 직접 지정할 수 있는 함수입니다.

인수로 FILE 구조체 변수의 포인터를 전달함으로써 표준 입출력 장치뿐만 아니라 파일로도 입출력을 진행할 수 있습니다.

 

표준 입출력 함수 중에서 스트림을 직접 지정할 수 있는 함수는 다음과 같습니다.

 

1. fgetc() 함수

2. fputc() 함수

3. fgets() 함수

4. fputs() 함수

5. fscanf() 함수

6. fprintf() 함수


fgetc() 함수

fgetc() 함수는 지정된 스트림으로부터 하나의 문자를 읽어 들이는 함수입니다.

이 함수는 읽기에 성공하면 읽은 문자를 반환하고, 파일의 끝에 도달하면 EOF를 반환합니다.

 

fgetc() 함수의 원형은 다음과 같습니다.

원형

#include <stdio.h>

int fgetc(FILE *stream);  


fputc() 함수

fputc() 함수는 지정된 스트림에 문자 하나를 출력(저장)하는 함수입니다.

이 함수는 저장에 성공하면 저장한 문자를 반환하고, 저장에 실패하면 EOF를 반환합니다.

 

fputc() 함수의 원형은 다음과 같습니다.

원형

#include <stdio.h>

int fputc(int c, FILE *stream);  

 

다음 예제는 fputc() 함수와 fgetc() 함수를 이용하여, 해당 파일의 모든 문자를 한 문자씩 읽어 들여 출력하는 예제입니다.

예제

#include <stdio.h>

#include <stdlib.h>

 

int main(void)

{

  char ch;

 

    /* 파일 open */

    FILE* ptr_file = fopen("text_readonly.txt", "r")// "C언어 파일 입출력" 문자열이 저장된 파일

    ...

    if(ptr_file != NULL)

    {

      while(EOF != (ch = fgetc(ptr_file))) // fgetc() 함수를 사용하여 파일로부터 문자 한 개를 읽어들임.

        {

          fputc(ch, stdout);               // fputc() 함수를 사용하여 모니터에 문자 한 개를 출력함.

        }

    }

 

    /* 파일 close */

    ...

    return 0;

}  

실행 결과

C언어 파일 입출력

 

위 예제의 ②번 라인에서는 fgetc() 함수가 반환하는 값을 char형 변수인 ch에 저장하고 있습니다.

하지만 C언어의 fgetc() 함수는 char형이 아닌 int형의 값을 반환하는 함수입니다.

즉, 위 예제에서는 int형으로 반환된 값을 char형 변수에 저장하는 것이므로, 반환값의 상위 3바이트가 잘려나가게 될 것입니다.

 

따라서 파일의 끝에 도달했을 때 반환되는 EOF 값인 -1의 16진수 값 '0xFFFFFFFF'도 '0xFF'로 저장될 것입니다.

그러므로 while 문은 현재 파일의 끝인 EOF를 읽은 것인지, 아니면 단순히 16진수 데이터인 '0xFF'를 읽은 것인지를 알 수가 없게 됩니다.

 

또한, EOF와 변수 ch를 비교할 때 EOF는 int형 값이므로, 변수 ch의 char형 값은 int형 값으로 자동 변환됩니다.

이때 만약 변수 ch가 signed char형이라면, EOF는 '0xFFFFFFFF'로 제대로 변환되므로 별문제가 발생하지 않습니다.

하지만 변수 ch가 unsigned char형이라면, EOF는 '0x000000FF'로 변환되므로 위의 while 문은 무한히 반복될 것입니다.

 

위와 같은 문제점을 가지고 있으므로, fgetc() 함수의 반환값은 다음과 같이 반드시 int형 변수로 저장해야 합니다.

예제

int main(void)

{

  int ch;

    ...

    if(ptr_file != NULL)

    {

        while(EOF != (ch = fgetc(ptr_file))) // fgetc() 함수를 사용하여 파일로부터 문자 한 개를 읽어들임.

        {

            fputc(ch, stdout);                 // fputc() 함수를 사용하여 모니터에 문자 한 개를 출력함.

        }

    }

    ...

}


fgets() 함수

fgets() 함수는 지정된 스트림으로부터 문자열을 읽어 들이는 함수입니다.

 

fgets() 함수의 원형은 다음과 같습니다.

원형

#include <stdio.h>

char *fgets(char * restrict s, int n, FILE * restrict stream)

 

이 함수의 첫 번째 인수는 읽은 문자열이 저장될 주소이며, 세 번째 인수는 스트림을 결정할 FILE 구조체 변수의 포인터입니다.

두 번째 인수로 전달받은 최대 입력 문자 개수보다 하나 적은 수의 문자를 읽거나, 파일의 끝에 도달할 때까지 문자를 읽습니다.

이 함수는 읽기에 성공하면 읽은 문자열이 저장된 주소를 반환하고, 파일의 끝에 도달하거나 읽기에 실패하면 NULL을 반환합니다.

 

fgets() 함수는 문자를 읽어 들이는 도중에 개행 문자('\n')를 만나게 되면 곧바로 읽기를 종료합니다.

그리고 지금까지 읽어 들인 문자들이 C언어에서 문자열로 인식되도록 맨 마지막에 널 문자('\0')를 자동으로 추가해 줍니다.


fputs() 함수

fputs() 함수는 지정된 스트림에 문자열을 출력(저장)하는 함수입니다.

 

fputs() 함수의 원형은 다음과 같습니다.

원형

#include <stdio.h>

int fputs(const char * restrict s, FILE * restrict stream);  

 

이 함수의 첫 번째 인수는 쓰고자 하는 문자열의 주소이며, 두 번째 인수는 스트림을 결정할 FILE 구조체 변수의 포인터입니다.

인수로 전달된 스트림이 stdout이면 모니터에 문자열을 출력하고, 파일이면 문자열을 해당 파일에 저장합니다.

이 함수는 쓰기(저장)에 성공하면 음수가 아닌 값을 반환하고, 저장에 실패하면 EOF를 반환합니다.

 

다음 예제는 fputs()함수와 fgets() 함수를 이용하여, 파일에서 문자열을 읽어 들여 다른 파일로 옮겨 저장하는 예제입니다.

예제

#include <stdio.h>

#include <stdlib.h>

 

int main(void)

{

    char str[100];

 

    /* 파일 open */

    FILE* ptr_src = fopen("text_readonly.txt", "r");

    FILE* ptr_dst = fopen("text_writeonly.txt", "w");

    ...

    while(fgets(str, 100, ptr_src) != NULL) // fgets() 함수를 사용하여 파일로부터 문자열을 읽어들임.

    {

        fputs(str, ptr_dst);                // fputs() 함수를 사용하여 파일에 문자열을 옮겨적음.

    }

    puts("text_readonly.txt 파일의 모든 내용이 text_writeonly.txt 파일로 옮겨졌습니다.");

 

    /* 파일 close */

    ...

    return 0;

}  

실행 결과

파일을 성공적으로 열었습니다!

text_readonly.txt 파일의 모든 내용이 text_writeonly.txt 파일로 옮겨졌습니다.

파일을 성공적으로 닫았습니다!


fscanf() 함수

fscanf() 함수는 지정된 스트림으로부터 다양한 서식 변환 문자를 이용하여 문자열을 읽어 들이는 함수입니다.

 

fscanf() 함수의 원형은 다음과 같습니다.

원형

#include <stdio.h>

int fscanf(FILE * restrict stream, const char * restrict format, ...);  

 

이 함수의 첫 번째 인수는 스트림을 결정할 FILE 구조체 변수의 포인터이며, 두 번째 인수는 읽어 들일 문자열의 서식입니다.

이 함수는 읽기에 성공하면 읽어 들인 변수의 개수를 반환하고, 읽기에 실패하면 EOF를 반환합니다.


fprintf() 함수

fprintf() 함수는 지정된 스트림에 다양한 서식 변환 문자를 이용하여 문자열을 출력(저장)하는 함수입니다.

 

fprintf() 함수의 원형은 다음과 같습니다.

원형

#include <stdio.h>

int fprintf(FILE * restrict stream, const char * restrict format, ...);  

 

이 함수의 첫 번째 인수는 스트림을 결정할 FILE 구조체 변수의 포인터이며, 두 번째 인수는 출력할 문자열의 서식입니다.

이 함수는 쓰기(저장)에 성공하면 저장한 문자열의 크기를 바이트 단위로 반환하고, 실패하면 음수를 반환합니다.

 

다음 예제는 fprintf()함수와 fscanf() 함수를 이용해 서식에 맞춰 문자열을 읽어 들여 모니터에 출력하는 예제입니다.

예제

#include <stdio.h>

#include <stdlib.h>

 

int main(void)

{

    int scan_num, int_num;

    double double_num;

    char str[100];

 

    /* 파일 open */

    FILE* ptr_file = fopen("text_fscanf.txt", "r");

    ...

    // fscanf 함수를 사용하여 파일로부터 문자열을 서식에 맞춰서 읽어들임.

    while(scan_num = (fscanf(ptr_file, "%d %lf %s", &int_num, &double_num, str)) != EOF)

    {         

        // fprintf 함수를 사용하여 모니터에 서식에 맞춰서 문자열을 옮겨적음.         

        fprintf(stdout, "%d %f %s\n", int_num, double_num, str);

    }

    

    /* 파일 close */

    ...

    return 0;

}

실행 결과

파일을 성공적으로 열었습니다!

123 3.14 C언어

파일을 성공적으로 닫았습니다!


연습문제