파일 처리 함수 - 2

순차파일 입출력함수와 랜덤파일 입출력함수, 랜덤파일의 위치제어.

  • 학습 목표
    1. 순차파일을 만들고 읽기.
    2. 랜덤파일 만들고 읽기.
    3. 랜덤파일의 위치 제어.

주요 용어

  • 레코드(record) : 파일을 구성하는 논리적인 기본 단위.
  • 텍스트 모드(textmode) : \n과 CR/LF 사이의 변환과정을 거치는 파일 모드.
  • 2진 모드(binary mode) : \n과 CR/LF 사이의 변환과정 없는 파일 모드.
  • 랜덤파일의 위치제어 : fseek()를 사용하여 랜덤파일의 특정부분을 입출력하는 것..

순차파일 입출력 함수

순차파일 출력함수

만들어진 파일에 자료를 기록하는 함수.

  • putc(), fputc(), fputs(), fprintf()

putc()

  • 문자 단위의 파일 출력함수.
  • fputc()와 유사.
  • 형식 : putc(문자변수, 파일포인터변수);
  • 사용 예 : putc(c, fp);
  • 기능 : fp가 가리키는 파일에 변수 c에 있는 문자 출력.
  #include <stdio.h>
  #include <stdlib.h>

  void main()
  {
    //  파일 포인터 선언
    FILE *fp;
    char c;

    // 파일 생성이므로 텍스트 쓰기모드로 오픈.
    fp = fopen("putc.tt.txt", "w");

    //  파일 개방 여부 체크. -> 에러메세지와 프로그램 종료.
    if (fp == NULL)
    {
      printf("FAIL TO OPEN FILE");
      exit(1);
    }

    //  문자 출력의 끝 확인.
    while ((c = getchar()) != EOF)
    {
      // 문자를 파일로 출력.
      putc(c, fp);
    }

    printf("END OF WHILE!");
    fclose(fp);
  }

fputs()

  • 문자열을 파일로 출력.
  • 형식 : fputs(문자열변수, 파일포인터변수);
  • 사용 예 : fputs(s, fp);
  • 기능 : 지정된 파일에 문자열(하나의 레코드) 출력.
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  void main() {
    char name[64];
    FILE *fp;
    //  텍스트 쓰기모드 개방하고, 에러시 프로그램 종료.
    if ((fp = fopen("02_fputs.tt.txt", "w")) == NULL) {
      puts("CAN NOT OPEN FILE");
      exit(1);
    }

    gets(name);
    while (strcmp(name, "end")) {
      // 하나의 문자열에 개행문자 추가.
      strcat(name, "\n");
      // 문자열을 fp가 가르키는 파일에 수록.
      fputs(name, fp);
      gets(name);
    }

    printf("BYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

fprintf()

  • 지정된 형식을 가지로 파일에 자료를 출력.
  • 여러 항목의 복합적인 자료로 구성된 레코드를 저장할 때 유용.
  • 형식 : fprintf(파일포인터변수, "출력형식", 변수);
  • 사용 예 : fprintf(fp, "%s %d\n", a, b);
  • 기능 : 지정된 형식대로 자료를 파일포인터 변수가 가리키는 곳에 출력.
  #include <stdio.h>
  #include <stdlib.h>

  void main()
  {
    FILE *fp;
    char no[10], name[10];
    int mid, term, rep, att, i;

    if ((fp = fopen("03_fprintf.tt.txt", "w")) == NULL)
    {
      puts("CAN NOT OPEN FILE");
      exit(1);
    }

    //  stdout : 모니터를 가리키는 특수한 파일포인터.
    fprintf(stdout, "insert no name mid term rep att.");

    for (i = 0; i < 5; ++i)
    {
      scanf("%s %s %d %d %d %d", no, name, &mid, &term, &rep, &att);
      // 지정된 형식으로 자료를 파일에 출력.
      fprintf(fp, "%10s %8s %3d %3d %3d %3d\n", no, name, mid, term, rep, att);
    }

    printf("BYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

C 언어에서 입출력 장치를 파일 개념으로 처리

  • 자동적으로 3개의 표준 파일에 대한 포인터를 생성함.
  • 이러한 표준 파일에 대해서는 다로 파일포인터를 선언할 필요가 없음.
표준파일 파일 포인터 대응 장치
입력 stdin 키보드
출력 stdout 모니터
에러 stderr 모니터

순차파일 입력함수

파일 출력함수에 의해 만들어진 순차파일의 저장된 자료를 읽어내는 함수.
자료를 읽을 때는 파일의 끝에 있는 EOF 신호를 만날 때까지 읽을 수 있는 프로그램 작성.

  • getc(), fgetc(), fgets(), fscanf()

getc()

  • 문자 단위의 파일 입력함수.
  • fgetc() 함수와 유사.
  • 형식 : getc(파일포인터변수);
  • 사용예 : c = getc(fp);
  • 기능 : 지정된 파일로부터 한 문자를 읽어온다.
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    FILE *fp;
    char c;

    if ((fp = fopen("01_putc.tt.txt", "r")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    while ((c = getc(fp)) != EOF) {
      putchar(c);
    }

    printf("\n\nBYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

fgets()

  • 파일에 저장된 문자열 자료를 읽을 때 사용.
  • 읽어 낼 문자열의 길이를 반드시 명시.
  • 형식 : fget(문자열변수, 문자열 길이 + 1, 파일포인터 편수);
  • 사용 예 : fget(s, 40, fp);
  • 기능 : 지정된 파일로부터 해당 문자열 길이 만큼의 문자를 읽어 문자열 변수에 저장한다.
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    char name[20];
    FILE *fp;

    if ((fp = fopen("02_fputs.tt.txt", "r")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    //  파일의 끝에 도달할 때까지 읽기.
    while (fgets(name, 20, fp) != NULL) {
      printf("%s", name);
    }

    printf("\n\nBYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

scanf()

  • 숫자, 문자 등 복합적인 자료로 구성된 레코드를 읽을 때 사용.
  • 일반적으로 파일의 끝을 판별하는 feof()와 같이 사용.
  • 형식 : fscanf(파일포인터변수, "입력형식", 변수);
  • 사용 예 : fscanf(sp, "%s %d", &a, &b);
  • 기능 : 파일 포인터가 가리키는 곳으로부터 지정된 형식대로 자료를 읽어온다.
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    FILE *fp;
    char no[10], name[10];
    int mid, term, rep, att;

    if ((fp = fopen("03_fprintf.tt.txt", "r")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    printf("no name mid, term, rep, att\n");

    //  파일의 끝인지 확인하는 feof()
    while (!feof(fp)) {
      //  파일에 저장된 자료의 형식에 맞게 입력형식을 지정해야 함.
      fscanf(fp, "%10s %8s %3d %3d %3d %3d\n", no, name, &mid, &term, &rep, &att);
      printf("%-10s %-8s %4d %4d %4d %4d\n", no, name, mid, term, rep, att);
    }

    printf("\n\nBYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

레코드 추가를 위한 사용 모드

a a+ ab ab+

  • 형식 : fp = fopen("파일명", "a");
  • 사용 예 : fp = fopen("파일명", "a");
  • 기능 : 이미 만들어진 순차파일의 끝에 새로운 레코드 추가(append).
  #include <stdio.h>

  void main() {
    FILE *fp;
    //  레코드 추가 모드로 파일 개방.
    fp = fopen("04_tt.dat", "a");
    //  파일이 없으르모 새 파일 생성 후 새 내용 기록.
    fputs("asdf \n", fp);
    fputs("qwer \n", fp);
    fputs("zxcv \n", fp);
    fputs("qaz \n", fp);
    fputs("wsx \n", fp);

    fclose(fp);
  }

랜덤파일 처리 (random file)

  • 파일의 임의의 위치에서 자료를 읽거나 쓸 수 있음.

  • 레코드의 길이가 일정함.

  • 순차파일에 비해

    • 장점 : 레코드 탐색이 빠르고 효과적.
    • 단점 : 기억공간 낭비.

랜덤파일 열기

일반적으로 랜덤파일을 입출력할 때는 2진 모드로 파일을 개방.

  • 2진 모드의 특징
    • 텍스트 파일보다 적은 기억공간.
    • 레코드의 길이를 개발자가 결정.
    • 파일 포인터의 위치 변경 가능.

랜덤파일 입출력 함수

fwrite()

  • 레코드의 길이를 지정.
  • 자료저장 변수는 포인터 형.
  • 형식 : fwirte(저장자료변수, 레코드길이, 레코드개수, 파일포인터);
  • 사용 예 : fwrite(name, 10, 1, fp);
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  void main()
  {
    FILE *fp;
    char name[10];

    //  2진 파일 쓰기 모드 개방.
    if ((fp = fopen("08_fwrite.dat", "wb")) == NULL)
    {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    gets(name);

    while (strcmp(name, "END"))
    {
      //  2진 파일 쓰기.
      fwrite(name, 10, 1, fp);
      gets(name);
    }

    fclose(fp);
  }

fread()

  • 읽기에 성공하면 읽은 레코드 수를 리턴.
  • 형식 : fread(읽을자료변수, 레코드길이, 레코드개수, 파일포인터);
  • ex : fread(name, 10, 2, fp);
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    FILE *fp;
    char name[10];

    //  2진 파일 읽기 모드 개방.
    if ((fp = fopen("08_fwrite.dat", "rb")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    while (1) {
      //  레코드의 개수가 1이 아닌 값이 리턴되면 파일은 끝난다.
      if (fread(name, 10, 1, fp) != 1)
        break;

      puts(name);
    }

    fclose(fp);
  }

랜덤파일 위치 제어

레코드의 길이가 일정하기 때문에, 자료의 위치를 제어할 수 있음.

fseek()

  • 파일 포인터를 임의의 위치로 이동시키는 함수.
  • 랜덤파일의 특정부분을 입출력 할 수 있음.
  • 형식 : fseek(파일포인터_변수, 이동할_상대위치, 기준위치를_지정하는*모드);
  • ex : fseek( fp, 2 * REC_size, SEEK_SET );

기준위치 지정모드

stdio.h에 정의됨

기준위치모드 동일기호 설명
0 SEEK_SET 파일의 시작위치
1 SEEK_CUR 현재 파일포인터의 위치
2 SEEK_END 파일의 끝 위치

 

  #include <stdio.h>
  #include <string.h>

  void main()
  {
    char str[10];
    FILE *fp = fopen("sample6.txt", "wt");

    fputs("1234567890", fp);
    fclose(fp);

    fp = fopen("sample6.txt", "rt");
    fseek(fp, 7, SEEK_SET);
    fgets(str, 4, fp);
    printf("print 3 str from 7 : %s\n", str);
    // 890

    fseek(fp, -2, SEEK_CUR);
    fgets(str, 3, fp);
    printf("print 2 char before 2 char cur loc : %s\n", str);
    // 90

    fseek(fp, -9, SEEK_END);
    fgets(str, 6, fp);
    printf("print 5 str from 9 char before last : %s\n", str);
    // 23456

    fclose(fp);
  }

728x90
반응형

'Language > C' 카테고리의 다른 글

[C] 메모리 동적 할당  (0) 2021.01.03
[C] 파일 처리 함수 - 1  (0) 2021.01.01
[C] 구조체와 공용체 - 2  (0) 2021.01.01
[C] 구조체와 공용체 -1  (0) 2020.12.27
[C] 배열과 포인터 - 3  (0) 2020.12.27

+ Recent posts