파일의 마지막 줄을 읽은 후에 ifstream.eof ()가 TRUE를 반환하지 않는 이유는 무엇입니까?


11

초보자가 ifstream을 읽기 시작하면 본능은 일반적으로 다음과 같은 루프를 사용하여 파일을 읽는 것입니다.

while (!ifstream.eof()
{
...
}

그러나이 코드를 사용했을 때 파일의 마지막 줄을 두 번 읽을 때까지 멈추지 않았다는 것을 알았습니다. C ++ 프로그래머는 이것이 실제로 파일을 읽는 방법이 아니라고 지적합니다. 대신, 파일을 읽어야하는 사람은 다음과 같은 루프를 사용하는 것이 좋습니다.

while (ifstream >> someVar)
{
...
}

첫 번째 코드가 항상 제대로 작동하지 않는 이유는 무엇입니까?


중복이 있다고 생각했지만 여기서는 찾을 수 없습니다. stackoverflow에 중복이 많이 있습니다.
David Hammen 17 년

답변:


4

while (!ifstream.eof())파일의 끝에 도달하지만 읽으려고 한 경우가 아니라 표시 할 때 C와 C ++의 스트림 / 파일을 예측하지 않기 때문에 루프는하지 작업을 수행 과거 파일의 끝.

파일의 마지막 행이 개행 ( \n) 문자로 끝나는 경우 대부분의 읽기 작업은 해당 문자를 발견했을 때 읽기를 중지하고 파일의 마지막 문자 인 것을 감지하지 못합니다. 다음 읽기 조치에서 더 많은 문자가 추가되어 읽기가 해당 문자를 추출하는 데 성공할 수도 있습니다.

스트림 추출 연산자 ( while (ifstream >> someVar))를 사용하는 루프 는 올바른 유형의 항목을 추출 할 수없는 경우 스트림 추출 연산자의 결과가 false로 평가되므로 작동합니다. 읽을 문자가 남아 있지 않은 경우에도 마찬가지입니다.


4

그러나 C ++ 프로그래머는 항상 발생하는 것은 마지막 행을 두 번 읽은 후에야 cin.eof ()가 "true"를 반환하지 않는다는 것입니다.

그것은 일어나고있는 것이 아닙니다. (가) eofbit부울에 어떠한 변환하는 역할을한다 ( stream::operator bool(또는 operator void*이전의 C ++에서)). 만 badbit하고 failbit참여하고 있습니다.

공백으로 구분 된 숫자가 포함 된 파일을 읽고 있다고 가정합니다. 주변의 루프 cin.eof()는 필연적으로 잘못되었거나 if테스트 로 가득 차 있습니다 . EOF까지는 읽지 않습니다. 당신은 숫자를 읽고 있습니다. 따라서 코드가 그 논리를 표현하게하십시오.

while (stream >> some_var) {
    process_value(some_var);
}

이것은 파일의 마지막 행으로 끝나 0 42\n든 막 그대로 0 42(파일의 마지막 행 끝에 새 줄도 없음) 작동합니다. 파일이로 끝나는 경우 0 42\n마지막으로 읽은 값은 값 42를 검색하고 해당 줄 끝 표시자를 읽습니다. EOF 마커는 아직 읽지 않았습니다. 이 함수 process_value는로 호출됩니다 42. 스트림 추출 연산자 >> 다음에 호출이 EOF를 판독하고, 아무것도 추출 된 이후, 양 eofbitfailbit설정한다.

반면에 파일이 0 42(마지막 줄 끝에 줄 바꿈)으로 끝나는 것으로 가정하십시오. 마지막으로 읽은 값은 EOF 마커에서 끝나는 42 값을 검색합니다. 아마도 당신은 42를 처리하고 싶을 것입니다. 이것이 eofbit입력 스트림 부울 변환 연산자에서 역할을하지 않는 이유 입니다. 다음에 스트림 추출 연산자 >>를 호출하면 기본 기계 eofbit가 이미 설정되어 있음을 빠르게 알 수 있습니다. 이것은 빠르게 설정합니다 failbit.

첫 번째 코드가 항상 제대로 작동하지 않는 이유는 무엇입니까?

루프 조건으로 EOF를 확인하지 않아야하기 때문입니다. 루프 조건은 수행하려는 작업, 예를 들어 스트림에서 숫자 추출을 표현해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.