rewind 함수에 대해 알아보겠습니다. 이것은 stream의 파일 위치 지시자를 시작 위치로 옮기는 함수입니다.

 

 별 게 없어 보입니다. 사실 이는, 다음과 같습니다.

 

 다만, error 지시자가 초기화가 되고 안 되고는 다릅니다. 이는 링크에서 except that the error 구문을 해석하시면 알 수 있습니다. 이제 예제를 몇 개 보도록 하겠습니다.

 

 


 먼저 아래 예제를 보도록 하겠습니다.

 

 

 문자열을 입력받고, 입력 버퍼를 초기화 하기 위해서, rewind(stdin); 을 호출해 주었습니다. 다음에 문자 하나를 입력받습니다. 의도대로 동작했을까요?

 

 

 chogahui를 입력하고 엔터를 입력했습니다. 프로그램의 의도는, 다음에 소문자를 입력받는 것이였습니다. 그런데, 엉뚱한 문자인 개행 문자를 입력 받았습니다. 의도대로 동작하지 않았습니다. 어떻게 된 일일까요?

 

 

 프로그램을 다음과 같이 작성해 봅시다. 다음에 컴파일을 한 후에, 실행 프로그램을 strace로 보겠습니다.

 

 

 mprotect, munmap이 나오고, fstat이 나온 다음에, brk가 나오고, lseek가 나옵니다. 그런데 이것의 리턴 값이 -1이라고 되어 있습니다. ESPIPE. 탐색이 잘못되었다고 나옵니다. 즉, 제 환경에서 stdin은 SEEKABLE 하지 않았습니다. rewind가 내부적으로 어떠한 함수를 호출했고, 그것이 또 내부적으로 lseek를 호출했다는 것은 어떻게 알 수 있을까요?

 

 5번째 줄을 주석 처리하고 다시 컴파일을 한 다음에, 실행 파일을 strace로 돌려 보겠습니다.

 

 

 이번에는 lseek가 안 보였습니다. 그러므로, rewind가 내부적으로 lseek를 불렀다는 이야기가 됩니다. 직접적으로 불렀던, 그것이 부른 함수가 lseek를 불렀거나. 그런데 그 함수가 -1을 리턴했습니다. 결론적으로, stdin은 탐색을 할 수 없는 특수한 경우입니다. 그러니, 예제가 제대로 돌아갈 리가 없을 겁니다.

 

 

 seekable 하지 않은 경우, fseek도 실패할 겁니다.

 

 

 stdin을 1번째 인자로 넣었더니, -1을 출력하네요. seekable 하다, 그렇지 않다는 것도 스택 오버플로우에서 종종 보이는 키워드이므로, 알아두시면 도움이 될 듯 싶습니다.

 

 


 탐색이 가능한 경우에, 이 함수는, 파일 위치 지시자를 처음 위치로 돌려놓는 역할을 한다고 하였습니다. 아래 프로그램을 봅시다.

 

 _read 함수를 호출하고, 문제의 함수를 호출합니다. 다음에 _read를 호출합니다. _read는 계속 파일로부터 character 하나씩을 읽어옵니다. 처음에 file position indicator는 다음을 가리키고 있을 겁니다.

 

 'H'를 읽었다면, 다음에 'E'를 읽을 차례입니다.

 

 

 따라서 'E'를 가리킬 겁니다. EOF가 등장할 때 까지 읽었다면, 아래와 같은 상황이 될 겁니다.

 

 

 여기서, 읽을 위치를 가리키는 포인터를 처음으로 돌려놓는다는 것은, 아래를 의미합니다.

 

 

 이 상태에서, EOF가 나타날 때 까지 다시 읽으면, 'H', 'E', 'L', 'L', 'O' 순서대로 읽을 겁니다.

 

 

 1.txt에는 다음과 같은 내용이 있었습니다. Hello가 나온 뒤에 개행 문자가 나오고, 그 다음에 EOF입니다.

 

 

 따라서, 프로그램의 실행 결과는 Hello가 2번 출력되는 것입니다.