2019 1학기 응용프로그래밍 - 파일 처리 01 파일 열기 02 파일 저장과 내용 읽기 03 이진파일 처리 04 임의접근 파일 처리 05 파일 관련 함수들
함수 fopen() 파일을 처리하기 위해 먼저 함수 fopen()을 사용 함수 fopen()의 함수 원형은 다음과 같으며 헤더 파일 stdio.h 파일에 정의 함수 fopen()은 두 개의 문자열 인자를 사용, 반환 값은 FILE 포인터 struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE;
파일 열기 함수 fopen()에서 첫 번째 문자열은 처리하려는 파일 이름이고, 두 번째 문자열은 파일 처리 모드(읽기, 쓰기, 덧붙이기) 파일 “basic.txt” 에 자료를 쓰기 위해 모드 값 “w”를 사용 조건문 if를 위와 같이 함수 fopen()과 함께 사용하여 파일 열기에 실패할 경우 적당한 처리 (예: 에러 메시지 출력) 파일 처리가 모두 끝났으면 파일 포인터 f를 인자로 함수 fclose(f)를 호출하여 반드시 파일을 닫아야 함 함수 fopen()의 두 번째 인자인 파일 처리 모드의 종류 “r”, “w”, “a”, “r+”, “w+”, “a+” FILE *f; char fname[] = "basic.txt"; if ((f = fopen(fname, "w")) == NULL) printf( "파일 %s 열기 실패!\n“, fname); … fclose(f);
파일 처리 모드 파일 처리 모드 종류와 의미
함수 fprintf, fscanf 파일에 자료를 쓰거나 읽기 위하여 함수 fprintf()와 fscanf()를 이용 이 함수를 이용하기 위해서는 헤더 파일 stdio.h 파일을 포함 함수 fprintf()와 fscanf()의 함수 원형 첫 번째 인자는 입출력에 이용될 파일이고, 두 번째 인자는 입출력되는 문자열이며, 다음 인자들은 입출력될 변수 목록 함수 원형에서 기호 …은 여러 인자가 계속됨을 의미 함수 fprintf()와 fscanf()를 표준 입출력에도 이용 가능 즉 함수 fprintf()와 fscanf()의 첫 번째 인자에 각각 stdin 또는 stdout를 이용하면 표준 입력, 표준 출력으로 이용이 가능 기호 상수 stdin, stdout, stderr은 헤더 파일 stdio.h에 정의되어 있는 값으로 각각 표준입력, 표준출력, 표준에러를 의미 int fprintf(FILE *, const char *, ...); int fscanf(FILE *, const char *, ...); 표준 파일 키워드 장치(device) 표준입력 stdin 키보드 표준출력 stdout 모니터 화면 표준에러 stderr #define stdin (&_iob[0]) #define stdout (&_iob[1]) #define stderr (&_iob[2])
예제 basic.c #include <stdio.h> #include <stdlib.h> // 함수 exit()의 원형 int main() { char fname[] = “basic.txt“; char name[40]; FILE *f; int point; if ((f = fopen(fname, "w")) == NULL) { printf("파일이 열리지 않습니다.\n"); exit(1); } printf("이름과 성적을 입력하세요.\n"); scanf(“%s %d”, name, &point); fprintf(f, "이름: %s, 성적: %d\n", name, point); fclose(f);
함수 fgets()와 fputs() 함수 fgets()와 fputs() 함수 fgets() 인자 함수 fputs() 인자 이 함수도 헤더파일 stdio.h 파일에 다음과 같은 함수원형으로 정의 함수 fgets()는 문자열을 개행문자(\n)까지 읽어 개행문자도 함께 입력 문자열에 저장 마찬가지로 함수 fputs()는 문자열을 그대로 출력 함수 fgets() 인자 첫 번째 인자는 문자열이 저장될 문자 포인터이고, 두 번째 인자는 입력할 문자의 최대 수이며, 세 번째 인자는 입력 문자열이 저장될 파일 함수 fputs() 인자 첫 번째 인자는 출력될 문자열이 저장된 문자 포인터이고, 두 번째 인자는 문자열이 출력되는 파일 char *fgets(char *, int, FILE *); int fputs(char *, FILE *);
함수 fgetc()와 fputc() 문자 하나를 파일에 입출력하는 함수로 fgetc()와 fputc()를 제공 이 함수의 원형은 헤더파일 stdio.h에 정의 이 함수들은 문자 하나의 입출력 대상인 파일 포인터를 인자로 이용 문자의 표준 입력에 이용되는 getchar()는 fgetc(stdin) 문자의 표준 출력에 이용되는 putchar()는 fputc(stdout) int fgetc(FILE *); int fputc(int, FILE *);
함수 feof()와 ferror() 함수 feof() 함수 ferror() 이 함수는 헤더파일 stdio.h에 다음 함수 원형으로 정의 파일의 위치가 파일의 마지막(end of file)인지를 검사하여, 파일의 마지막이면 0이 아닌 값을, 파일의 마지막이 아니면 0을 반환 그러므로 표준입력에서 계속적으로 입력을 받는 구문으로 다음을 이용 가능 함수 ferror() 파일 처리에서 오류가 발생했는지 검사하는 함수 함수의 원형은 헤더파일 stdio.h에 정의 이전 파일 처리에서 오류가 발생하면 0이 아닌 값을 발생하고, 오류가 발생하지 않으면 0을 반환 int feof(FILE *); while (!feof(stdin)) { … } int ferror(FILE *);
예제 list.c 목적 조건 “list filename”을 입력 명령어 줄 인자를 활용, 두 번째 인자가 파일이름에 해당 파일의 내용을 표준출력으로 출력 조건 명령어 줄 인자를 활용, 두 번째 인자가 파일이름에 해당 이 파일이름에 해당하는 인자를 기술하지 않으면 간단한 사용법을 알리고 프로그램을 종료 파일 내용의 출력은 한 줄마다 맨 앞에 줄 번호를 출력 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *f; int ch, cnt = 0; if (argc != 2) { printf("사용법 : list filename\n“); exit(1); } if ( (f = fopen(argv[1], "r")) == NULL ) { printf("파일이 열리지 않습니다.\n"); printf("%4d: ", ++cnt); while ( (ch = fgetc(f)) != EOF ) { putchar(ch); if (ch == '\n') printf("%4d: ", ++cnt); printf("\n"); fclose(f);
텍스트 파일과 이진 파일 텍스트 파일 텍스트 파일의 내용은 모두 지정된 문자 코드(일반적으로 아스키 코드) 값을 갖고 있어, 그 내용을 텍스트 편집기로 확인할 수 있음 함수 fprintf()를 이용하여 정수형 변수 cnt에 저장된 값을 파일 f에 출력하는 과정 이진 파일 이진(binary) 파일은 C 언어의 자료형을 모두 유지하면서 바이트 단위로 저장하는 파일 이진 파일의 대표적인 예가 실행파일. 이러한 이진 파일은 텍스트 편집기로는 그 내용 확인 불가능
함수 fwrite와 fread 이진 파일 처리 인자와 반환 값 void * 이진(binary) 모드로 입출력을 처리하려면 함수 fwrite()와 fread()를 이용 함수 fwrite()는 헤더파일 stdio.h에 다음과 같은 함수원형으로 정의 함수 fread()는 이진 파일에 저장되어 있는 자료를 읽어 들이는 함수 인자와 반환 값 첫 번째 인자는 입출력될 자료의 주소 값이며, 두 번째 인자는 입출력될 자료의 바이트 크기이고, 세 번째 인자는 입출력될 단위 자료의 묶음 개수이고, 마지막 인자는 입출력될 파일 포인터 반환값은 파일에 입출력된 단위 자료형의 개수 void * 자료형 void *는 모든(임의의) 자료형의 주소값을 가질 수 있는 포인터 size_t fwrite(const void *, size_t, size_t, FILE *); size_t fread(void *, size_t, size_t, FILE *);
이진 파일 입출력 이해 함수 fwrite()를 이용하여 정수형 변수 cnt 값을 파일 f에 출력하는 과정 이진 파일 입출력 이해 함수 fwrite()를 이용하여 정수형 변수 cnt 값을 파일 f에 출력하는 과정 함수 fwrite()는 바이트 단위로 원하는 블록을 파일에 출력 함수 fwrite()에 의하여 출력된 이진 파일 자료는 함수 fread()를 이용하여 입력해야 함
예제 score.h와 score.c // score.h #include <stdio.h> struct pscore { int number; char name[40]; int mid; int final; }; typedef struct pscore pscore; #include <stdio.h> #include <stdlib.h> #include "score.h" int main() { char fname[] = "score.bin", line[80]; FILE *f; int cnt = 0; pscore score; if ((f = fopen(fname, "w")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); } printf("이름과 성적(중간, 기말)을 입력하세요.\n" ); fgets(line, 80, stdin); while ( !feof(stdin) ) { sscanf(line, "%s %d %d", score.name, &score.mid, &score.final); score.number = ++cnt; fwrite(&score, sizeof(pscore), 1, f); fclose(f);
파일 내부 위치 파일 위치 포인터 순차적, 임의 접근 파일을 열면 항상 파일 위치 포인터(file pointer)라는 것이 파일의 한 장소를 가리킴 파일 내부를 바이트 단위로 파일 내부 위치를 나타내는 값 파일 위치 포인터가 100L이라면 파일의 처음에서부터 100바이트 떨어진 위치에 현재 파일 포인터가 위치 파일 위치 포인터 값은 일반적으로 자료형 long으로 취급하므로 상수를 기술할 때 100L처럼 숫자 뒤에 L을 기술 파일 위치 포인터는 파일 내부에서 자료를 읽거나 쓰는 만큼 파일의 현재 위치에서 뒤로 이동 순차적, 임의 접근 파일에서 원하는 장소로 자유롭게 이동하는 것을 임의 접근(Random Access) 파일의 임의 접근을 처리하기 위해서는 파일 포인터를 자유 자재로 이동하는 함수 fseek()이 필요
함수 fseek() fseek() offset 함수 fseek()는 함수 원형이 헤더파일 stdio.h 파일에 정의 함수 fseek()는 파일 “fptr”의 기준점 “base”에서 “offset”만큼 떨어진 곳으로 파일 포인터를 위치하는 함수 offset 함수 fseek()에서 두 번째 인자는 long 형으로 기준점으로부터 떨어진 값을 말하며 흔히 오프셋(offset)이라 함 함수 fseek()에서 세 번째 인자는 정수형 기호 상수로 다음 세 가지 중의 하나를 이용 int fseek(FILE *fptr, long offset, int base) 기호 값 의미 SEEK_SET 파일의 시작 위치 SEEK_CUR 1 파일의 현재 위치 SEEK_END 2 파일의 끝 위치
기준 세가지 함수 fseek(f, 100L, SEEK_SET)의 호출은 파일 포인터를 파일의 처음 위치에서 100바이트 떨어진 위치로 이동시킨다. 함수 fseek(f, 100L, SEEK_CUR)의 호출은 파일 포인터를 파일의 현재 위치에서 100바이트 떨어진 위치로 이동시킨다. 함수 fseek(f, -100L, SEEK_END)의 호출은 파일 포인터를 파일 끝 위치에서 앞으로 100바이트 떨어진 위치로 이동시킨다.
int fseek(FILE *, long, int) 파일 관련 여러 함수 파일 위치 포인터와 관련된 함수로서 다음 세 가지 함수를 이용 함수 ftell()은 인자인 파일의 파일 위치 포인터를 반환하며 함수 rewind()는 파일 위치 포인터를 무조건 제일 앞으로 이동 함수 기능 int fseek(FILE *, long, int) 파일 위치 포인터를 세 기준점으로부터 오프셋만큼 이동 long ftell(FILE *) 파일의 현재 파일 위치 포인터를 반환 void rewind(FILE *) 파일의 현재 포인터를 0 위치(파일의 시작점)로 이동
파일 삭제, 이름 바꾸기 함수 remove() 함수 rename() 함수 remove()는 remove(“sample.txt”)와 같이 문자열로 지정된 파일을 삭제 함수 rename() 지정된 파일의 이름을 새로운 이름으로 바꾸는 역할을 수행 함수 rename()은 rename(“oldname.txt”, “newname.txt”)과 같이 앞의 파일이름을 뒤 파일이름으로 바꾸는 역할 함수 remove()와 rename()도 헤더 파일 stdio.h에 그 함수 원형이 정의