본문 바로가기

C++

c++ 16 ( 파일 입출력 1 )

File pointer

파일 포인터는 물리적 디스크의 파일에 접근하는 타입 구성요소에는 다음의 3가지가 있다.

  1.  파일의 시작 지점
  2.  파일의 종료 지점
  3.  현재 읽고 있는 위치

 

 

파일 포인터는 파일이 하드디스크에 저장이 되는데 하드디스크는 사실상 끈 형태로 되어있다.

디스크는 그냥 길다란 끈이 막 늘어져있다.

내가 원하는 파일이 텍스트 파일이다 하면 

컴퓨터는 그 텍스트 파일의 처음 지점에 포인터를 갖다 놓게 된다.

 모든 메모리는 byte의 길다란 끈으로 이루어져있고 

그 메모리를 읽이 위해서 어떤 포인터가 항상 존재하는데 

그 포인터를 통해서 그 위치에 있는 데이터를 가져와서 

적당히 처리를 해서 화면에 뿌리든 네트워크로 보내든 하는 것

 

파일도 똑같은 메모리 구조를 갖고있기 때문에 파일에 접근하기 위해서는 파일 포인터 활용

파일 포인터는 한 칸의 단위가 byte char의 크기로 이루어져있다.

 

 

C 형식 파일 입출력 (C 형식 File IO)

FILE* fopen (const char* filename, const char* mode);

  • filename : 대상 파일명 c 스타일 파일 이름
  • mode : 파일을 여는 방법

- w : 쓰기 (존재하지 않으면 새로 생성, 존재하면 지우고 다시 생성)

- r : 읽기 (존재하지 않으면 오류, 존재하면 처음부터 읽어나가기)

- a : 파일을 이어나가기 (존재하지 않으면 새로 생성, 존재하면 파일의 마지막부터 쓰기)

- w+ : 쓰기 또는 읽기 (존재하지 않으면 새로 생성, 존재하면 지우고 다시 생성)

- r+ : 쓰기 또는 읽기 (존재하지 않으면 오류, 존재하면 처음부터 읽어나가기)

- a+ : 이어나가기 또는 읽고 쓰기 (존재하지 않으면 새로 생성, 존재하면 파일의 마지막부터 쓰기)

(보통, w나 r+를 많이 쓴다)

 

 

 

파일 입출력의 여러가지 함수

 

char fgetc(FILE* fp);

: fp로부터 다음 char를 1개 읽는다, fp를 1만큼 뒤로 이동한다

 

char*fgets(char* buff, int size, FILE* fp);

: fp로부터 다음 char*를 size 만큼 읽는다. fp를 size만큼 뒤로 이동한다

 

int fscanf(FILE*fp, const char* str, ... );

: 우리가 익히 알고 있는 그 scanf 함수와 동일하게 사용

단, fp를 처음에 파라미터로 남겨야한다. fp는 읽은 만큼 뒤로 이동

몇개의 argument가 성공적으로 assign 되어있는지를 반환, 모두 실패시 EOF 반환

 

int fseek(FILE*fp, l ong pos, int origin);

: fp를 origin 기준으로 pos 만큼 이동한다. 

즉, 파일포인터를 어떠한 위치로 옮겨준다.

(origin : SEEK_SET, SEEK_CUR, SEEK_END)

  • SEEK_SET : fp의 최초 시작점
  • SEEK_CUR : fp의 현재 지점
  • SEEK_END : fp의 마지막

성공시 0, 실패시 0이 아닌 값을 반환

 

int fclose (FILE* fp);

: fp 파일 포인터 종료

성공시 0 리턴, 실패시 EOF 리턴

fclose를 해줘야 파일의 마지막 지점이 여기라고 기록을 해줌

파일을 열었으면 데이터를 처음부터 끝까지 다 가져오고 마지막에 fclose를 통해서 파일을 종료해야한다.

 

int feof (FILE* fp);

: fp 파일이 현재 EOF 인지 확인 (즉, 파일의 끝에 닿았는지의 유무를 확인)

EOF 라면 1 아니라면 0을 리턴

 

EOF (End Of File)

: 매크로 상수, stdio.h(cstdio) 에 정의됨

 

fwrite(void* target, size_t each_size, size_t total_size, FILE* fp);

  • target : void* (어떤 포인터라도 상관없다)
  •  each_size : target 의 각각의 byte 사이즈 (배열 사이즈) (사이즈 : byte단위 (char))
  •  total_size : target 의 each_size 의 크기를 기준 단위로한 전체 사이즈 (사이즈 : byte단위 (char))

: 이 target 이라고 되어있는 void* 에 어떤 값인 포인터변수를 각각의 사이즈 만큼

그리고 전체 사이즈 만큼 파일 포인터에다가 기록한다.

 

 

freed(void* target, size_t each_size, size_t total_size, FILE* fp);

: target 포인터를 size_t 만큼의 total_size 만큼 파일 포인터에서 읽어온다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>


int main() {
    
    FILE* infile = fopen("text.txt", "w");
    fprintf(infile, "Hello World");
    fclose(infile); 
    
    // Hello World라는 글자가 text.txt 파일에 만들어짐
    
    return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>


int main() {
    
    FILE* infile = fopen("text.txt", "r");
    char input[100];
    fscanf(infile, "%99[^\n]s", input);
    fclose(infile); 
    
    printf("%s", input); // Hello World 출력됨
    
    return 0;
}

 

숫자 출력

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>


int main() {
    
    FILE* infile = fopen("text.txt", "w");
    int value = 100;
    fprintf(infile, "%d", value);
    fclose(infile);
    
    // 100 이 저장되어있다.

    return 0;
}

 

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>


int main() {
    
    /* 487651 저장

    FILE* infile = fopen("text.txt", "w");
    int value = 487651;

    fwrite(&value, sizeof(int), 1, infile);
    // fwrite(주소값의 최초 위치, 내가 쓰고싶은 데이터의 사이즈, 배열크기, 파일포인터) 순서로 넣어준다

    fclose(infile); */
    
    FILE* infile = fopen("text.txt", "r");
    int value;
    fread(&value, sizeof(int), 1, infile);
    printf("%d", value);


    return 0;
}

 

저장과 읽어오는데 이런 식으로 할 수 있다.

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>


int main() {
    
    /* 저장
    FILE* infile = fopen("text.txt", "w");
    int value[5] = {1, 2, 5, 10, 20};
    fwrite(value, sizeof(int), 1, infile); // 배열의 이름은 포인터니까 value 앞에 &삭제
    fclose(infile);
     */
    
    // 읽어오기
    FILE* infile = fopen("text.txt", "r");
    int value[5];
    fread(&value, sizeof(int), 5, infile); // 5칸을 읽어오기
    fclose(infile);
    
    for(int i = 0; i < 5; i++) {
        printf("%d ", value[i]);
    }


    return 0;
}