이번 시간에는 c언어 fseek 함수를 배워보도록 하겠습니다. 이 함수는, 간단하게 요약하면 파일의 임의 위치에 접근하게 해 주는 함수입니다. 당연하게도, 탐색할 수 없는 파일이면, 이 함수를 호출하는 것이 무용지물일 거에요.

 


 먼저, 0123456789라는 내용을 적은 input.txt를 생성해 보겠습니다.

 

 

 cat input.txt를 하면, 0123456789가 출력이 될 겁니다. 같은 디렉토리에 있는 실행파일 fs는 input.txt의 내용을 읽고 쓰는 함수입니다. input.txt가 존재하기 떄문에, 파일을 여는 연산은 성공해야 할 듯 싶습니다.

 

 

 그런데 보기 좋게 fail이 뜹니다. 뭐가 문제일까요? 파일이 분명 있는데. 의심해 볼 만한 것 중에는 권한이 있습니다. 어떠한 User로 로그인이 되어 있는데, 그 User가 파일을 읽는 것은 가능하지만, 쓰는 것이 불가능하다면, permission 때문에 write 연산이 되지 않을 수도 있을 겁니다.

 

 

 권한을 확인해 보니, root에 대해서만 r 권한과 w 권한이 있습니다.

 

 

 그러면 권한을 666으로 바꾸면 해결이 되겠군요.

 

 

 다시 fs를 실행시키면, 정상적으로 실행이 된다는 것을 알 수 있어요. 그러면, fs.c에는 어떤 내용이 있었길래, 권한을 644로 주었더니 파일을 읽지 못한다고 떴을까요? 

 

 

 한 파일을 읽거나 update 작업을 수행하려는 경우, r+ 옵션을 줍니다. 제가 root 유저가 아니였고, 권한이 644로 주어진 경우에, root 이외의 유저에 대해서 write 연산이 허가되지 않은 작업입니다. 따라서, r+ 옵션으로 여는 것이 거부되었을 거고, file not exist가 떨어졌을 겁니다.


 이제 본론으로 들어가 보겠습니다. fseek는 다음과 같이 3개의 인자를 받습니다.

 

 이 중에서 offset이 양수이면, 위치 지시자를 기준점으로부터 offset 단위만큼 뒤로, 음수이면 offset 단위만큼 앞으로 이동합니다. 기준점은 3가지 종류가 있습니다.

 

 예를 들어, origin을 SEEK_SET으로 두고, offset을 1로 두었다면, 파일의 시작 위치에서 기준점으로부터 1만큼 간 위치를 뜻합니다. 예제 프로그램을 보도록 하겠습니다.

 

 

 input.txt 파일을 연 다음에, SEEK_SET으로부터 5만큼 이동한 위치에 있는 문자 하나를 읽어서 ch에 저장했습니다. 일단 여기까지만 보겠습니다. 파일에는 "0123456789"가 있었습니다. 파일의 처음 위치에는 '0'이 있었습니다. 그로부터 5만큼의 단위 이동을 하면, 어디를 가리키게 될까요? '5'를 가리키게 될 겁니다.

 

 

 그러니, ch = 5가 출력되는 것은 전혀 이상한 일이 아닙니다. 그리고, 현재 위치로부터 1만큼 앞쪽으로 단위 이동을 한 다음에 그 위치에 "ABC"를 찍습니다. 그러면, 파일의 내용이 0123ABC789가 찍혀야 할 듯 싶은데, 실제로는 01234ABC89가 찍혔습니다. 이것은 왜 그럴까요?

 


 ftell 함수는 간단하게 말해서, 위치 지시자의 위치를 리턴해 주는 함수입니다.

 

 우리는 파일 위치 지시자를 시작 위치로부터 5만큼 간 위치에 놓았습니다. 그리고, fscanf 함수로 문자를 하나 읽어버렸습니다. 그 다음에 ch와 ftell(fp)의 값을 출력했습니다. 결과가 어떻게 나올까요?

 

 

 ch의 값은 5가 나왔지만, cur의 값은 6이 나왔습니다. 이는 fscanf로 읽었을 때, indicator가 1만큼 뒤로 이동했다는 것을 의미합니다. SEEK_CUR의 값이 6이였는데, 거기에서 -1만큼 이동하면 5입니다. "01234ABC89"가 나오는 것이 이상하지 않습니다.

 

 

 그러면, 이렇게 작성하면, 어떻게 나올까요? 처음 위치로부터 5만큼 이동한 다음에, 그 위치로부터 -2만큼 지시자를 이동했습니다. 결론적으로, 첫 위치로부터 3만큼 뒷쪽으로 간 위치를 indicator가 가리킬 겁니다.

 

 

 "012ABC6789"가 찍힙니다.