태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

C++의 ifstream의 small buffer 문제

Posted 2009/03/03 15:11


댓글 하나가 운영자에겐 커다란 힘이 됩니다!

아래의 내용은 조영일님의 글을 스크랩한 내용입니다.
출처 : http://terzeron.net/wp/?p=753

C++ 프로그램에서 ifstream을 자주 사용하게 되는데, 주로 이 클래스의 멤버 함수인 getline()을 이용하여 한 줄씩 처리하는 경우가 대부분이다.

이럴 때 아무 생각없이 getline()에 사용할 buffer의 크기를 너무 작게 잡으면 해결하기 어려운 문제가 발생할 수 있다.

다음의 데이터를 포함한 텍스트 파일이 있다.

hello
world
Extracts characters from the input sequence and stores them as a c-string into the array beginning at s.
java
coffee

일반적으로 사용하는 코드는 다음과 같다. 물론 C++ 프로그래머마다 약간씩의 스타일의 차이는 있겠지만, Stroustrup의 C++ 책에도 getline()의 사용방식에 대해 특별한 제한이나 가이드를 두고 있지 않으므로 while loop에서 getline()을 단순 반복하는 것이다.


이 코드는 처음 두 줄만을 출력하고 20 바이트를 초과하는 입력을 만나게 되면 바로 종료하게 된다. getline()이 buffer overflow에 대해서 0을 반환하기 때문에 while loop를 탈출하게 되는 것이다.

hello
world

while loop를 분리하여 다음과 같은 코드를 사용하게 되면 어떻게 될까?

getline()에 대해서 체크를 하지 않기 때문에 무한 루프에 빠진다. EOF를 확인하도록 다음 코드를 써도 마찬가지이다.

그럼 EOF 대신에 fstream 객체의 상태를 확인하는 good() 함수를 사용하면 어떻게 될까?


그럼 EOF 대신에 fstream 객체의 상태를 확인하는 good() 함수를 사용하면 어떻게 될까?

딱 20바이트까지만 읽고 종료하게 된다. 파일의 나머지 부분을 읽지 못하는 것이다.

hello
world
Extracts characters

여태까지의 예제 코드들은 모두 원하는 결과를 내지 못했다. 이제 두 가지 선택이 존재한다.

첫번째는 버퍼 이상의 입력은 무시하고 다음 줄로 넘어가는 것이다.

두번째는 버퍼를 동적으로 늘려서라도 모두 읽어내는 것이다. 그러나 이 방법은 사용자의 입력을 무한히 받으려고 시도하다가 메모리 부족을 겪거나 스택 오버플로우로 인해 보안 상의 결점을 노출시키게 된다. 이 방법에 대한 자세한 설명은 생략한다.

첫번째 방법은 다음과 같이 구현할 수 있다. getline() 호출 후에 fstream의 상태를 체크해보는 것이다. fstream의 상태가 좋지 않지만 EOF는 아닌 상태라면 에러 상태를 초기화하고 다음 줄부터 다시 읽도록 하는 것이다.



hello
world
java
coffee

ignore() 함수를 호출하게 되면 버퍼보다 큰 입력의 (버퍼 크기만한) 뒷쪽 부분을 버리는 효과를 가진다. ignore() 함수를 호출하지 않는다면 다음과 같은 결과를 얻게 될 것이다.

hello
world
ing at s.
java
coffee

세번째 방법도 있긴 하다. gcount()를 이용하여 getline()이 읽어낸 데이터의 크기를 확인하여 버퍼 크기보다 작거나 같은지를 확인하는 것이다. do while loop으로 감싸면 된다. 개인적으로 그다지 좋아하는 스타일은 아니다. 

위의 정보가 도움이 되셨나요? 그렇다면 댓글 하나만 남겨주세요.
댓글 하나가 운영자에겐 커다란 힘이 됩니다!

« PREV : 1 : ... 90 : 91 : 92 : 93 : 94 : 95 : 96 : 97 : 98 : ... 436 : NEXT »