File pointer
파일 포인터는 물리적 디스크의 파일에 접근하는 타입 구성요소에는 다음의 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; } |
'C++' 카테고리의 다른 글
c++ 17 ( 람다 함수 ) (0) | 2022.02.27 |
---|---|
c++ 16 ( 파일 입출력 2 ) (0) | 2022.02.25 |
c++ 15 ( 기본 자료구조 - STL 기초 자료구조 활용 ) (0) | 2022.02.23 |
c++ 14 ( Generic 이라고도 불릴 수 있는 개념 ) (0) | 2022.02.22 |
c++ 13 ( const / static / extern ) (0) | 2022.02.19 |