언어/C언어

[C언어] 파일입출력 2 (fseek, ftell)

REAKWON 2018. 10. 21. 21:42

파일 입출력 2


간단하게 파일에서 읽고 쓰는 것은 이제 알겠습니다.


하지만 단순히 파일을 처음부터 차례대로 읽는 것이 아니라, 어떤 위치 이후에서 읽고 쓰는 것도 가능할까요?


할 수 있습니다. 바로 fseek함수를 이용해서 말이죠.


fseek

int fseek(FILE *stream, long int offset, int origin);


fseek함수는 파일의 위치를 임의로 조작할 수 있습니다. 파일은 순차적으로 읽고 씁니다. 하지만 특정위치에 있는 데이터를 읽거나 쓸 필요가 있는 것이죠.


stream은 파일을 의미합니다.

offset은 origin에서 얼마만큼 이동할 것인지 나타냅니다.

origin은 기준 위치를 지정합니다.




우리가 fread를 여러번 호출해도 순차적으로 읽어올 수 있는 이유는 파일포인터때문입니다. 파일포인터는 현재 파일의 위치를 기억하고 있습니다. 그렇기 때문에 순차적으로 읽을 수 있는 거지요.






우리는 파일포인터의 위치를 임의로 지정하여 특정 위치의 데이터를 읽고 쓰는 것이 가능합니다. 파일포인터에 관해서는 세가지 매크로가 있는데요.


SEEK_SET : 파일의 처음

SEEK_CUR : 지금 현재 파일포인터 위치

SEEK_END : 파일의 끝


특정 위치에서 읽기

특정 위치에 값을 읽어오는 코드를 한 번 보겠습니다.


text.txt

ABCDEFGHIJ


#include <stdio.h> #include <string.h> int main() { FILE *fp = fopen("text.txt", "r"); char buf[30]; memset(buf, 0, sizeof(buf)); fseek(fp, 5L, SEEK_SET); // fseek(fp, -4L, SEEK_END); fread(buf, sizeof(char), sizeof(buf), fp); printf("%s\n", buf); fclose(fp); return 0; }


파일의 처음위치부터 5를 건너뛰면 파일포인터는 F 앞을 가리키고 있습니다.


결과

FGHIJ



반면에 파일 끝에서 4칸 앞은 offset이 음수가 됩니다. 처음 fseek을 주석처리하고 밑의 주석을 해제하고 실행해보세요. 결과는 이렇습니다.


GHIJ



특정 위치에 쓰기

반면 특정 위치에 쓰는 것도 가능합니다. 단! 파일을 열때 r+모드로 여세요. 


text.txt

ABCDEFGHIJ



#include <stdio.h>
#include <string.h>
int main() {
	FILE *fp = fopen("text.txt", "r+");
	char buf[30]="_INSERT_";

	fseek(fp, -5, SEEK_END);
	fwrite(buf, sizeof(char),strlen(buf), fp);
	
	fclose(fp);
	return 0;
}


파일 끝에서 5칸 앞에 _INSERT_라는 문자열을 추가하는 코드입니다. F 앞의 위치입니다. 

하지만 그 자리를 덮어쓰게 됩니다. 그래서 결과는 이렇습니다.


text.txt

ABCDE_INSERT_




ftell

파일 포인터의 위치를 알아옵니다. 

long int ftell(FILE *stream)


열었던 파일을 매개변수로 넣어주면 끝입니다.


성공시 0을 포함한 양수를 반환합니다.


text.txt

ABCDEFGHIJ


#include <stdio.h>

int main() {
	FILE *fp = fopen("text.txt", "r+");
	int pos;
	fseek(fp, 5, SEEK_SET);
	pos = ftell(fp);
	printf("현재 파일 포인터 : %d\n", pos);
	fclose(fp);
	return 0;
}


결과

현재 파일 포인터 : 5


ftell을 응용해서 파일의 크기도 알아올 수 있습니다.

#include <stdio.h>

int main() {
	FILE *fp = fopen("text.txt", "r+");
	int pos;
	fseek(fp, 0, SEEK_END);
	pos = ftell(fp);
	printf("파일크기 : %d\n", pos);
	fclose(fp);
	return 0;
}


파일 속성에서 알아본 크기는 10바이트입니다. 위의 코드의 결과는 어떨까요?


파일크기 : 10


바이트 단위로 일치한다는 것을 알 수 있네요.


파일에 대해서는 다음에 또 이야기하도록 합시다.

반응형