[C언어] 파일 입출력과 동적할당

르랑·2021년 7월 26일
1

Programming Language C

목록 보기
10/10

파일 입출력

☆ 기본파일 입출력

  - FILE * fopen = (cosnt char * filename, const char * mode);
   구조체    주소           스트림을 형성할 파일명     스트림 종류를 문자열 형태로
  - 예를 들면 출력스트림은 FILE * fp = fopen("data.txt", "wt");, 입력스트림은 FILE * fp = fopen("data.txt", "rt");
  - 스트림의 소멸은 int fclose(FILE ( stream);으로, 성공시 0을 실패시 EOF를 반환.
  - 버퍼를 비우는 방법은 int ffluch(FILE * stream); 단, 입력 버퍼를 대상으로 호풀할 수 없음. 사용은 fflush(fp);
  - 파일로부터 데이터 읽는 방법은 int ch; ch = fgetc(fp); 이는 파일에 저장된 문자 하나를 반환.


☆ 파일의 개방모드

1. 읽기 위한 스트림 vs. 쓰기 위한 스트림

  - 데이터 READ 스트림: 읽기만 가능
  - 데이터 WRITE 스트림: 쓰기만 가능
  - 데이터 APPEND 스트림: 쓰되 덧붙여 쓰기만 가능
  - 데이터 READ/WRITE 스트림: 읽기, 쓰기 모두 가능
  - 스트림 종류를 표현하는 문자열. 이는 작업 변경마다 메모리 버퍼를 비워야 함.
    1) r 읽기 가능. 파일 없으면 에러.
    2) w 쓰기 가능. 파일 없으면 생성.
    3) a 파일 끝에 덧붙여 쓰기 가능. 파일 없으면 생성.
    4) r+ 읽기, 쓰기 가능. 파일 없으면 에러.
    5) w+ 읽기, 쓰기 가능. 파일 없으면 생성.
    6) a+ 읽기, 덧붙여 쓰기 가능. 파일 없으면 생성.

2. 텍스트 파일 vs. 바이너리 파일

  - 텍스트 파일은 사람이 인식할 수 있는 문자를 담은 파일, 바이너리 파일은 그 이외에 컴퓨터가 인식할 수 있는 데이터를 담은 파일.
  - 개행의 표현 방식때문에 이를 구분함. MS-DOS는 \r\n Mac은 \r Unix계열은 \n
  - 파일을 텍스트 모드로 개방하면 자동 변환이 됨(rt wt at r+t w+t a+t). 하지만, 바이너리 데이터는 변환이 일어나면 안됨(rb wb ab r+b w+b a+b). tb를 붙이지 않으면, 텍스트 모드로 개방.


☆ 바이너리 입출력

   - size_t fread(void * buffer, size_t size, size_t count, FILE * stream);
   - FILE * stream에서 size_t size의 크기 데이터를 size_t count만큼 가져와서 void * buffer에 저장.
   - 성공시 전달인자 count, 실패 또는 파일이 끝날시 count보다 작은 값 반환.


☆ 텍스트 데이터 + 바이너리 데이터 동시 입출력

   - fprintf(fp, "%s %c %d", name, sex, age); fscanf(fp, "%s %c %d", name, &sex, &age);
   - 구조체 변수를 하나의 바이너리 데이터로 인식하고 처리. 즉, 구조체 변수를 통째로 저장하고 읽음.
     fwrite((void *)&myfren1.name, sizeof(myfren1), 1, fp);
     fread((void *)&myfren2, sizeof(myfren2), 1, fp);


☆ 파일 위치 지시자

   - 데이터의 일부를 읽어야 하는 경우, FILE 구조체 멤버 중 파일의 위치 정보가 저장된 멤버를 이동시켜야 함.
   - 이는 fgets, fputs, fread, fwrite 등이 호출이 될 때마다 참조, 갱심됨.
   - fseek(파일주소, long offset 바이트 크기, wherefrom)으로 이동시킬 수 있음.(stream으로 전달된 파일 위치 지시자를 wherefrom에서부터 offset만큼 이동.)
   - SEEK_SET은 파일의 맨 앞(0), SEEK_CUR은 파일 현재 위치(1), SEEK_END는 파일의 맨 끝(2)
   - 현재 파일 위치 지시자의 위치를 확인하기 위해서는 ftell(FILE * stream)을 사용.



동적할당

☆ C언어 메모리 구조

   - 코드영역: 코드가 저장되는 메모리 공간. CPU는 이 영역에서 하나씩 가져가서 실행.
   - 데이터영역: 전역변수, static 변수가 할당되어, 프로그램 시작과 동시에 메모리 할당, 종료시까지 남음.
   - 스택영역: 지역변수, 매개변수가 할당. 함수를 빠져나가면 소멸.
   - 힙영역: 프로그래머가 원하는 시점에 변수를 할당하고, 소멸하도록 지원하는데, 이러한 유형의 변수들이 할당되는 메모리.


   - 유사한 성향의 데이터를 묶어서 저장을 하면, 관리가 용이해지고 메모리의 접근 속도가 향상되기 때문에 메모리를 나눔.


☆ 프로그램 처리

   - 데이터 flow
     1) 전역변수 할당, static 변수 할당.
     2) main함수 호출.
     3) 지역변수할당, 매개변수할당.(함수에서 빠져나오면, 소멸)
     4) main함수의 return문 실행
     5) 프로그램 종료
     6) 메모리 전체 반환(전역 변수 소멸)


☆ 메모리 동적 할당

   - 생성과 소멸의 시기가 지역 변수나 전역 변수와 다른 유형의 변수로, 힙 영역에 메모리를 할당하고 해제.
     - 할당은 void * 변수명 = malloc(바이트크기);, 해제는 free(변수명)
     - malloc은 type을 규정하지 않아, 알아서 형변환을 해야함.
     - calloc 함수: void * calloc(size_t elt_count, size_t elt_size); malloc과 같이, 메모리를 동적으로 할당. 단, calloc는 모든 비트를 0으로 초기화.
     - realloc 함수: void * realloc(void * ptr, size_t size); 원래 할당된 메모리를 늘릴 수 없으나, 힙 영역은 realloc으로 가능함.


0개의 댓글