[리눅스 시스템 프로그래밍] 5.3 FILE 구조체

표준 입출력 함수에서는 작업할 파일에 관한 정보를 FILE 구조체 형식으로 기억합니다. FILE 구조체는 C 컴파일러에 따라 조금씩 차이가 있지만 파일 기술자, 버퍼 시작 주소, 버퍼에서 입출력할 위치 주소, 작업 관련 플래그 등을 제공합니다.

struct _IO_FILE{

int _fileno; //파일 기술자

char *_IO_read_ptr; //읽기 버퍼에서 현재 읽을 위치 주소

char *_IO_read_base; //읽기 버퍼의 시작 주소

char *_IO_read_end; //읽기 버퍼에 처리할 데이터가 있는 영역의 끝 주소

char *_IO_write_ptr; //쓰기 버퍼에서 현재 기록할 위치 주소

char *_IO_ write _base; //쓰기 버퍼의 시작 주소

int _flags;

…중략…

};

typedef struct _IO_FILE FILE;

다음은 표준 입력의 정보를 출력하는 예제 코드입니다.

/***********************************************************************
* ex_filetype.c                                                        *
* example source – about struct FILE                                   *
***********************************************************************/

#include <stdio.h>
#include <unistd.h>

void print_fileinfo(FILE *fp);
int main()
{
    getchar();
    print_fileinfo(stdin); 
    getchar();
    print_fileinfo(stdin); 
    getchar();
    print_fileinfo(stdin); 
    getchar();
    print_fileinfo(stdin); 
    return 0;
}
void print_fileinfo(FILE *fp)
{
    printf(“===========================================\n”);
    printf(“_fileno: %d\n”, fp->_fileno);
    printf(“_flags: %#x\n”, fp->_flags);
    int dcnt = (fp->_IO_read_end – fp->_IO_read_ptr);
    printf(“data count:%d\n”,dcnt);
    printf(“_IO_read_base:%s\n”, fp->_IO_read_base);
    printf(“_IO_read_ptr:%s\n”, fp->_IO_read_ptr);
}

실행 화면을 보면 _fileno는 0임을 알 수 있습니다. 이는 파일 기술자입니다. 표준 출력은 1, 표준 에러는 2입니다. 표준 입력의 _IO_read_base는 입력 버퍼의 시작 주소이며 _IO_read_ptr은 입력 버퍼에서 현재 처리할 위치 주소입니다. 실행 화면을 보면 getchar 함수 호출을 처리할 때마다 한 칸씩 이동함을 알 수 있어요. 그리고 _IO_read_end는 입력한 데이터가 있는 영역의 끝(실제로는 마지막 데이터가 있는 다음 위치)입니다. 따라서 현재 처리하지 않은 데이터 개수는 _IO_read_end – _IO_read_ptr입니다.

[그림 5.3] ex_filetype 실행 화면
[그림 5.3] ex_filetype 실행 화면

다음은 표준 출력의 정보를 출력하는 예제 코드입니다.

/***********************************************************************
* ex_filetype2.c                                                       *
* example source – about struct FILE                                   *
***********************************************************************/

#include <stdio.h>
#include <unistd.h>

void print_fileinfo(FILE *fp);
int main()
{
    putchar(‘e’);
    print_fileinfo(stdout); 
    putchar(‘h’);
    print_fileinfo(stdout); 
    putchar(‘p’);
    print_fileinfo(stdout); 
    putchar(‘u’);
    print_fileinfo(stdout); 
    putchar(‘b’);
    print_fileinfo(stdout);
    putchar(‘\n’); 
    return 0;
}
void print_fileinfo(FILE *fp)
{
    fprintf(stderr,“===========================================\n”);
    fprintf(stderr, “_fileno: %d\n”, fp->_fileno);
    fprintf(stderr, “_flags: %#x\n”, fp->_flags);
    int dcnt = (int)(fp->_IO_write_ptr – fp->_IO_write_end);
    fprintf(stderr, “data count:%d\n”, dcnt);
    fprintf(stderr, “_IO_write_base:%s\n”, fp->_IO_write_base);
}

출력 결과를 보면 표준 출력의 파일 기술자는 1임을 알 수 있어요. 그리고 현재 출력 버퍼에 기록을 하였지만 출력하지 않은 문자 개수는 _IO_write_ptr – _IO_write_end로 확인할 수 있어요.

[그림 5.4] ex_filetype2 실행 화면
[그림 5.4] ex_filetype2 실행 화면