본문 바로가기

C 언어/임베디드 C

구조체를 사용한 파일 입출력

/*학생의 레코드를 키보드로부터 입력받아 write()함수를 이용하여 구조체 단위로
 * 파일에 기록하고, 다시 열어서 read()함수로 읽어서 화면에 출력하는 프로그램*/

#include
 <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>

typedef struct    //STUDENT 구조체의 정의
{
  int id;      //학생번호
  char name[20];
  int year, month, day;
}
STUDENT;

int main()
{
  STUDENT st;
  int infd, outfd;

  //출력파일의 생성
  if((outfd = creat("d11-10.out", S_IREAD | S_IWRITE)) < 0)
  {
    printf("file create error!\n");
    exit(-1);
  }
  close(outfd);    //파일의 속성을 기록하기 위해서 닫음

  //출력파일을 쓰기 위해서 오픈
  if((outfd = open("d11-10.out", O_WRONLY)) < 0)
  {
    printf("file open error!\n");
    exit(-1);
  }

  //키보드로부터 학생 데이터를 입력받아 파일에 기록
  while(1)
  {
    printf("\n학번이 음수이면 입력이 종료됨\n id : ");
    scanf("%d"&st.id);
    if(st.id<0break;
    printf("name : ");
    scanf("%s", st.name);
    printf("birthday(yy/mm/dd) : ");
    scanf("%d/%d/%d"&st.year, &st.month, &st.day);
    write(outfd, &st, sizeof(STUDENT));    //출력파일에 기록
  }
  close(outfd);

  //출력파일을 읽기 위새서 열기
  if((infd = open("d11-10.out", O_RDONLY)) < 0)
  {
    printf("file open error!\n");
    exit(-1);
  }

  //출력파일을 읽어서 화면에 출력
  while(read (infd, &st, sizeof(STUDENT)) >= sizeof(STUDENT))
  {
    printf("\nid : %d", st.id);
    printf("\nname : %s", st.name);
    printf("\nbirthday(yy/mm/dd)\n : %d/ %d/ %d", st.year, st.month, st.day);
  }
  close(infd);
  return 0;
}


결과



write(outfd, &st, sizeof(STUDENT));
키보드로부터 구조체 변수 st자료를 입력받은 뒤 파일에 입력받은 데이터를 저장하는 명령문이다. 두 번째 인수에 주소연산자 &가 붙은 것은 write()함수의 두 번째 인수가 버퍼의 주소를 넘겨받기 때문이다.
예를 들면, int형 변수 num을 파일에 기록할 경우 명령문은 다음과 같다.

int num = 5;
write(fd, &num, sizeof(int));

read(outfd, &st, sizeof(STUDENT));
read()함수도 write()함수와 같이 모든 자료형을 파일로부터 읽을 수 있다.

저수준 입출력에서의 임의접근
저수준 파일 입출력에도 고수준의 경우처럼 임의의 접근이 가능하며, 이때 사용되는 함수들은

long tell(int handle);
long lseek(int handle, long offset, int fromwhere);

위 함수의 사용방법은 고수준 파일 입출력의 ftell()함수와 fseek()함수와 동일하다.
이들 함수와의 차이점은 파일포인터 대신 파일기술자가 인수로 넘겨지는 것 뿐이다.

위 소스에서 입력받은 학생의 정보를 저장한 뒤, 파일의 모든 내용을 출력하였으나, lseek() 함수를 사용하여 임의의 학생에 대한 정보를 파일로부터 읽어올 수 있다.

lseek(infd, 2 * size(STUDENT), SEEK_SET);
이 명령문은 파일 내의 현재위치를 3번째 학생의 레코드가 저장된 위치에 설정한다. 여기서 read()함수를 이용해서 3번째 학생의 레코드를 버퍼로 읽어올 수 있고, write()함수를 이용해서 새로운 3번째 학생의 레코드를 기록할 수 있다.

hexaview로 읽어 온 d11-10.out

'C 언어 > 임베디드 C' 카테고리의 다른 글

버블 정렬  (0) 2011.07.01
리다이렉션(redirection)  (0) 2011.06.29
malloc(), free()  (0) 2011.06.22
달팽이 배열  (0) 2011.06.22
어셈블리 기본소스  (0) 2011.06.15