본문 바로가기
Developer/C, C++

[C/C++] C언어 파일 읽기쓰기 및 포인터 관리

by Doony 2021. 9. 7.

최근 OS 강의를 시작하면서 기본적인 파일 입출력 코드를 짜는 일이 생겨서 정리하고자 합니다.
C언어에 대해, 포인터 개념에 대해 warm up 형식으로 배우고 가는 취지로 간단하게 작성해봤습니다. 저처럼 c에 대해 이해도가 없는 분들께 도움이 되길 바라며...


file 읽기

파일 읽기는 다음 코드와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define BUFFERSIZE 128
  FILE* fp = fopen(filename, "r");  // read txt file
 
  char *buffer; // 메시지를 읽을 buffer
  int size// size of the file
 
  fseek(fp, 0, SEEK_END);    // move the pointer to the end
  size = ftell(fp);          // get location of the pointer ( = size of the file)
 
  buffer = malloc(BUFFERSIZE + 1);    // allocate dy-mem for file BUFFERSIZE + 1 byte (last Null)
  memset(buffer, 0, BUFFERSIZE + 1);  // memset as 0 for allocated memory
 
  fseek(fp, 0, SEEK_SET);                // move pointer to the first
  fread(buffer, 1, BUFFERSIZE , fp);    // read and save it on the buffer about BUFSIZE
cs

텍스트 파일을 읽어들인다고 했을 때, 글자 하나하나가 메모리 주소에 할당됩니다. (char buffer) 따라서 fseek에서 fp 포인터를 사용하게 되면, 파일의 위치에 따라 작업을 할 수 있게 됩니다. fseek는 차례대로 포인터, OFFSET, 기준점을 얘기하며, 기준점에 대한 것은 다음과 같습니다.

  • SEEK_SET: 시작점에서 오프셋
  • SEEK_CUR : 현재 위치에서 오프셋
  • SEEK_END : 끝점에서 오프셋

위 예제에서 SEEK_END, 즉 끝점에서 오프셋을 0으로 두는 방식으로 전체 파일의 SIZE를 구할 수 있었습니다.


fread 함수를 통해서 읽은 값을 buffer에 저장할 수 있는데요. fread는 차례대로 저장할 버퍼, 읽어들일 바이트, 반복할 횟수, 포인터입니다.

위 예제 같은 경우, 미리 정의한 버퍼 사이즈만큼 반복해서 값을 읽어오게 했습니다. 바이트와 횟수에 대한 변수를 바꿔서 넣어도 값은 동일합니다.

모든 작업을 완료했다면, fclose(fp)를 통해 포인터를 닫습니다.
또한, malloc를 통해 dynamic memory를 부여한 경우, memory leakage를 방지하기 위해 free(buffer)가 반드시 필요합니다. (예제에는 반영하지 않고, 추후 상세 포스팅 올리겠습니다.)


file 쓰기

이번에는 파일을 쓰는 방법입니다. 코드는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
 
  FILE *fp = fopen(filename, "w");    // open txt file in write mode
 
  ### PREDEFINED buffer;
 
   // add read message on the file   
  fseek(fp, 0, SEEK_END);
  fputs(buffer, fp);
 
cs

먼저, fseek를 통해 어느 지점부터 입력을 시작할 것인지 설정할 수 있습니다. 위에서 설명한 SEEK_END를 사용하게 되면, 포인터를 파일의 가장 끝단에 위치하라는 말이 됩니다. 즉, 파일에 내용이 미리 입력되어 있었다면, 가장 끝에 와서 입력을 시작하라고 하는 것입니다.


그리고 나서 fput을 통해, 그 포인터(fp)에서 message를 입력하는 명령을 사용합니다.

댓글