`fgetc`, `getc` 함수

fgetc, getc 함수 (fgetc, getc)

파일에서 문자 하나씩 읽어야 할 때 쓰는 함수가 fgetc예요. 한 글자씩이지만, 반복문과 함께 쓰면 파일 전체를 순서대로 훑는 기본 읽기 루프가 돼요. 거의 같은 일을 하는 getc라는 매크로도 있는데, 이 둘의 차이를 짚어 볼게요.

출처: cppreference

본문

함수 원형

<stdio.h>에 정의돼 있어요.

int fgetc( FILE* stream );   // (1)
int getc ( FILE* stream );   // (2)

설명 (Explanation)

  1. 주어진 입력 스트림에서 다음 문자를 읽어요.
  2. fgetc와 같지만, getc가 매크로로 구현되어 있다면 stream을 두 번 이상 평가할 수 있어요. 그래서 해당 인자로 부수 효과(side effect)가 있는 표현식은 쓰면 안 돼요.

매개변수 (Parameters)

  • stream — 문자를 읽어올 스트림

반환값 (Return value)

성공하면 얻은 문자를 unsigned char로 변환한 값을 int로 돌려줘요.

실패하면 EOF를 돌려줘요. 실패 원인이 파일 끝(end-of-file) 조건이라면 stream에 eof 표시를 설정하고(feof() 참고), 다른 오류라면 오류 표시를 설정해요(ferror() 참고).

예제 (Example)

파일을 열어 내용을 한 글자씩 읽어 표준 출력에 복사하는 표준 C 입출력 읽기 루프예요.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    const char* fname = "/tmp/unique_name.txt"; // or tmpnam(NULL);
    int is_ok = EXIT_FAILURE;

    FILE* fp = fopen(fname, "w+");
    if (!fp)
    {
        perror("File opening failed");
        return is_ok;
    }

    fputs("Hello, world!\n", fp);
    rewind(fp);

    int c; // note: int, not char, required to handle EOF
    while ((c = fgetc(fp)) != EOF) // standard C I/O file reading loop
        putchar(c);

    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
    {
        puts("End of file is reached successfully");
        is_ok = EXIT_SUCCESS;
    }

    fclose(fp);
    remove(fname);
    return is_ok;
}

가능한 출력:

Hello, world!
End of file is reached successfully

여기서 한 가지 짚어 두고 싶은 게 있어요. 반환값을 받는 변수를 char가 아니라 int로 선언했죠? EOFchar에 다 담기지 않을 수 있으니, 이런 읽기 루프에서는 반드시 int를 써야 해요.

같이 보기 (See also)

  • getchar — stdin에서 문자 읽기
  • fputc/putc — 파일 스트림에 문자 쓰기
  • ungetc — 문자를 파일 스트림에 되돌려 놓기