feof()는 filepointer의 현재 위치에 대해 eof를 확인합니까? 아니면 현재 파일 포인터 옆에 위치를 확인합니까?feof()는 C에서 어떻게 작동합니까?
도움 주셔서 감사합니다.
feof()는 filepointer의 현재 위치에 대해 eof를 확인합니까? 아니면 현재 파일 포인터 옆에 위치를 확인합니까?feof()는 C에서 어떻게 작동합니까?
도움 주셔서 감사합니다.
모든 FILE
스트림에는 호출자가 이미 파일 끝을지나 읽으려고했는지 여부를 나타내는 내부 플래그가 있습니다. feof
은 해당 플래그를 반환합니다. 이 플래그는 현재 파일 위치가 파일의 끝인지 여부를 나타내지 않고 이전 읽기가 파일 끝을지나 읽으려고했는지 여부 만 나타냅니다.
예를 들어, 2 바이트를 포함하는 파일을 읽을 때 어떤 일이 발생하는지 살펴 보겠습니다.
방식 때문에feof
작품의
f = fopen(filename, "r");
while (!feof(f)) {
c = getc(f);
putchar(c);
}
는 파일 끝 플래그는 다음과 같습니다 다음 파일을 읽을 때 EOF를 사용하는 잘못된 방법은 왜
f = fopen(filename, "r"); // file is opened
assert(!feof(f)); // eof flag is not set
c1 = getc(f); // read first byte, one byte remaining
assert(!feof(f)); // eof flag is not set
c2 = getc(f); // read second byte, no bytes remaining
assert(!feof(f)); // eof flag is not set
c3 = getc(f); // try to read past end of the file
assert(feof(f)); // now, eof flag is set
이입니다 한 번 설정하십시오 getc
은 파일의 끝을 지나서 읽으려고합니다. getc
은 문자가 아닌 인 EOF
을 반환하고 putchar
은 루프를 작성하면 을 쓰려고 시도하여 오류 또는 가비지 출력이 발생합니다. 이 파일의 끝을지나 읽기를 시도하는 경우, 또는 에러가 발생했을 경우 읽는 동안 특수 값 EOF
을 반환 getc
:
모든 C 표준 라이브러리 입력 방법은 성공 또는 실패의 표시를 반환합니다. 특수 값은 파일 끝과 오류에 대해 동일하게 이며, 여기에서 feof
을 사용하는 적절한 방법이 있습니다. 파일 끝과 오류 상황을 구별하는 데이 값을 사용할 수 있습니다. ferror
:
f = fopen(filename, "r");
c = getc(f);
if (c == EOF) {
if (feof(f))
printf("it was end-of-file\n");
else
printf("it was error\n");
}
오류 상황에 대한 FILE
객체에 대한 또 다른 내부 플래그가있다. "파일 끝이 아니라"대신 오류를 테스트하는 것이 더 명확합니다. C에서 파일을 읽을 수 관용적 방법은 다음과 같이이다 :
f = fopen(filename, "r");
while ((c = getc(f)) != EOF) {
putchar(c);
}
if (ferror(f)) {
perror(filename):
exit(EXIT_FAILURE);
}
fclose(f);
(일부 오류 검사를 간결, 여기 예에서 생략되었습니다.)
feof
기능은 매우 드물게 유용합니다.
구현 방법을 알면 feof
의 작동 방식을 더 잘 이해할 수 있습니다. 다음은 7th Edition Unix stdio 라이브러리가 feof
을 어떻게 구현하는지 단순화 된 버전입니다. 현대 라이브러리는 스레드 안전성, 효율성 향상 및보다 명확한 구현을 제공하는 코드를 추가하는 것과 매우 유사합니다.
extern struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
char _flag;
char _file;
} _iob[_NFILE];
#define _IOEOF 020
#define feof(p) (((p)->_flag&_IOEOF)!=0)
#define getc(p) (--(p)->_cnt>=0? *(p)->_ptr++&0377:_filbuf(p))
int
_filbuf(FILE *iop)
{
iop->_ptr = iop->_base;
iop->_cnt = read(fileno(iop), iop->_ptr, BUFSIZ);
if (iop->_cnt == 0) {
iop->_flag |= _IOEOF;
return(EOF);
}
return(*iop->_ptr++ & 0377);
}
STDIO 라이브러리는 각 파일 _base
가리키는 내부 버퍼를 포함하는 구조를 유지한다.버퍼의 현재 문자는 _ptr
이며, 사용 가능한 문자 수는 _cnt
입니다. scanf
과 같이 많은 상위 수준 기능의 기반이되는 getc
매크로는 버퍼에서 문자를 반환하려고 시도합니다. 버퍼가 비어 있으면 _filbuf
을 호출하여 버퍼를 채 웁니다. _filbuf
은 read
으로 전화 할 것입니다. read
이 0을 반환하면 더 이상 사용할 수있는 데이터가 없음을 의미하고 _filbuf
은 _IOEOF
플래그를 설정합니다. feof
은 true를 반환 할 때마다이 값을 검사합니다.
위의 내용에서 알 수 있듯이 feof
은 파일 끝에 도달 한 문자를 처음 읽으려고하면 (또는 라이브러리 함수가 사용자를 대신하여 시도 할 때) true를 반환합니다. 이것은 다양한 기능의 동작에 미묘한 영향을 미칩니다. 단일 문자를 포함하는 파일을 고려하십시오 : 숫자 1
. getc
으로 해당 문자를 읽은 후 _IOEOF
플래그가 설정되어 있지 않으므로 feof
은 false를 반환합니다. 아무도 아직 파일의 끝을 읽으려고 시도하지 않았습니다. getc
을 다시 호출하면 _IOEOF
플래그가 설정되어 read
으로 호출되며 이로 인해 feof
이 true를 반환합니다. 그러나 fscanf("%d", &n)
을 사용하여 같은 파일에서 번호를 읽은 후 fscanf
은 정수의 추가 숫자를 읽으려고 시도하기 때문에 feof
은 즉시 true를 반환합니다.
간단하고 정확 :-) – cnicutar
죄송합니다. 흥분하고 조금 확장했습니다. –
더 나아졌습니다. – cnicutar