티스토리 뷰

C | C++

스트림 에러 처리

야라바 2018. 6. 4. 21:11
728x90

☞ feof, ferror, clearerr

<stdio.h>

int feof(FILE *stream);
int ferror(FILE *stream);
void clearerr(FILE *stream);

대부분의 스트림 처리 함수들은 파일 끝에 도달하거나 작업에 실패하면 EOF(-1)을 리턴합니다. 그렇지만 이 경우 파일 끝과 파일 오류를 구분할 수 없으므로 feof()로 파일끝에 도달했는지, ferror()로 스트림에 오류가 있는 확인하는 것이 좋습니다. feof()는 지정한 스트림이 파일끝이 아니면 0, 파일끝이면 0이 아닌값을 리턴합니다. ferror()는 지정한 스트림에 오류가 있었으면 0이 아닌값을 리턴합니다. 발생한 오류가 무엇이었는지는 errno를 통해서 확인할 수 있습니다. 파일끝 인식과 오류 인식은 스트림 오브젝트에 있는 플래그를 보고 처리하는데 clearerr()로 이 플래그들을 초기화하고 입출력을 재시도 할 수 있습니다. 문제는 원인이 해결되지 않은 상태에서 재시도하는 것은 미처리 버퍼의 문제도 있고 재시도해도 또다시 오류가 발생하므로 원인을 조치하는 것이 맞습니다. 다만 파일끝 플래그는 파일 위치 조정 함수를 사용하면 자동적으로 초기화 됩니다.



☞ 예제

if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive )  
{
    int c = '*';  
    size_t n;  
    for ( n = 0; n < max_size &&  
        (c = getc( base_yyin )) != EOF && c != ' n'; ++n )  
        buf[n] = (char) c;  
    if ( c == ' n' )  
        buf[n++] = (char) c;  
    if ( c == EOF && ferror( base_yyin ) )  
        YY_FATAL_ERROR( "input in flex scanner failed" );  
    result = n;  
}  
else  
{  
    errno=0;  
    while ( (result = (int) fread(buf, 1, max_size, base_yyin))==0 && ferror(base_yyin))  
    { 
        if( errno != EINTR)  
        {  
            YY_FATAL_ERROR( "input in flex scanner failed" );  
            break;  
        }  
        errno=0;  
        clearerr(base_yyin);  
    }  
} 

위의 코드는 PostgreSQL DBMS의 파서코드의 일부로 fread() 호출 과정에서 에러가 발생한 경우 에러 원인이 EINTR인 경우에는 clearerr()로 플래그를 초기화하고 재시도하는 것을 확인할 수 있습니다.




728x90

'C | C++' 카테고리의 다른 글

저수준 입출력(Low-Level Input/Output)  (0) 2018.06.17
스트림 위치 및 버퍼 관리  (0) 2018.06.04
형식화된 입력  (0) 2018.06.04
가변 인수 포맷 입출력  (0) 2018.06.04
형식화된 출력, printf 총정리  (0) 2018.06.04