98. 파일 입출력 – ftell, fseek

이 외에도 입출력 작업의 위치를 확인하는 ftell 함수와 작업 위치를 변경하는 fseek 함수 등이 있어요.

long ftell(FILE * fp);
int fseek(FILE * fp, long offset, int origin);

ftell 함수는 입력 인자로 입출력 작업 FILE *를 전달하면 작업 위치를 반환하는 간단한 함수예요.
fseek함수는 FILE *외에도 세번째 인자로 기준이 되는 매크로 상수와 두번째 인자로 기준에서의 상대적 위치(음수도 가능)를 전달하여 작업 위치를 설정할 수 있어요.
세번째 인자로 들어가는 인자는 시작 위치를 의미하는 매크로 상수 SEEK_SET, 현재 위치를 의미하는 SEEK_CUR, 끝을 의미하는 SEEK_END가 올 수 있죠.

#define SEEK_CUR    1
#define SEEK_END    2
#define SEEK_SET    0

다음 코드는 먼저 회원 데이터를 파일 스트림에 출력한 후에 닫아요.
그리고 찾고자 하는 순서 번호를 입력받아 회원 정보를 출력하는 코드예요.
간단하게 주석을 달아놓았으니 확인해 보세요.

//회원 데이터를 파일에 출력한 후 닫고 찾고자 하는 순서 번호를 입력받아 회원 정보를 출력  
#include <stdio.h>
 
#define MAX_NAME_LEN    20
typedef struct{
    char name[MAX_NAME_LEN+1];
    int age;
}Member;
 
#define MAX_MEMBERS 10
int main (void)
{
    FILE * fp;
    int n;
    Member members[MAX_MEMBERS]=
    {
        {"홍길동",20},{"강감찬",15},{"을지문덕",22},{"이순신",19},{"김구",30},
        {"안중근",30},{"박찬호",35},{"김연아",17},{"아이유",20},{"주니엘",20}        
    };
    Member member;     
 
    fopen_s (&fp,"data.txt","wb");//쓰기 모드로 파일 열기
    if (fp==NULL) 
    {
        perror ("error fopen");
        return 0;
    }
    //출력 파일 스트림에 회원 정보 출력
    if(fwrite(members,sizeof(Member),MAX_MEMBERS,fp) != MAX_MEMBERS)
    {
        printf("출력 오류\n");
        return 0;
    }
    fclose (fp);//출력 파일 스트림 닫기
 
    printf("회원 순서 번호 입력(1~%d)  : ",MAX_MEMBERS);
    scanf_s("%d",&n);//조회할 회원 순서 번호 입력
    if((n<1)||(n>MAX_MEMBERS))//순서 번호가 범위를 벗어날 때
    {
        printf("입력 오류\n");
        return 0;
    }
 
    fopen_s (&fp,"data.txt","rb");//읽기 모드로 파일 열기
    if (fp==NULL)
    {
        perror ("error fopen");
        return 0;
    }
 
    fseek(fp,sizeof(Member)*(n-1),SEEK_SET);//파일 position 이동
    fread(&member,sizeof(Member),1,fp);  //회원 데이터 읽기
    printf("이름: %s 번호: %d\n",member.name,member.age);//회원 데이터 출력
    
    fclose (fp);//입력 파일 스트림 닫기
    return 0;
}

출력

회원 순서 번호 입력(1~10) : 10
이름: 주니엘 번호: 20

파일 입출력 관련 함수에 대해 보다 깊이있는 학습을 원하는 분들은 유닉스 시스템 프로그래밍에 관한 서적을 보세요.
그리고 파일 입출력 기능을 제공하는 다양한 형태의 프로그램을 작성해 보세요.
프로그램에서 관리하는 데이터의 논리적 메모리 구조를 그려본 후에 입출력 기능을 구현하는 습관을 갖어보세요.