C 프로그래밍및실습 14. 파일입출력 세종대학교 목차 1) 파일입출력개요 2) 파일입출력절차 3) 텍스트파일 vs. 이진파일 4) 텍스트파일의입출력함수 5) 이진파일의입출력함수 ( 심화내용 ) 6) 기타파일입출력관련함수 ( 심화내용 ) 2
표준입출력 1) 파일입출력개요 표준입력장치 ( 키보드 ) 를통해입력받아처리하여표준출력장치 ( 모니터 ) 를통해결과를보여주는것 표준입력함수 : scanf(), getchar(), gets() 표준출력함수 : printf(), putchar(), puts() 프로그램이종료되면입출력의결과는사라짐 표준입력장치 표준입력함수 C 프로그램 표준출력함수 표준출력장치 3 1) 파일입출력개요 프로그램의실행 / 종료여부와무관하게데이터를보존하고싶다면?? 파일입출력 데이터를파일로부터읽거나파일로출력하는것 C 언어는파일입출력함수를라이브러리함수로제공 입력파일 출력파일 C 프로그램 파일에서읽기 파일에쓰기 4
1) 파일입출력개요 프로그램과파일간데이터교환 파일 C 프로그램 stream 스트림 (stream) 프로그램과파일사이에교환되는연속적인바이트흐름 ( 데이터의논리적흐름 ) 구체적으로, FILE 구조체와파일버퍼를통해구현 일관된입출력작업을수행 입출력효율을향상 장치들로부터독립된프로그래밍이가능 프로그램이데이터를처리하는속도와입출력장치에서수행되는입출력속도의차이를줄이는역할수행 5 1) 파일입출력개요 다음프로그램을실행시키고, 실제파일이생성되었는지확인해보자. main.c #include <stdio.h> 현재작업중인소스프로그램파일 (main.c) 이있는디렉터리 int main() double weight = 78.3; int age = 31; FILE *fp; fp = fopen("test.txt", "w"); 실행결과 : text.txt 이생성되고, 파일내용은다음과같음! fprintf(fp, "FIRST FILE TEST!\n"); fprintf(fp, "%.2f %d\n", weight, age); fclose(fp); return 0; 6
1) 파일입출력개요 현재작업디렉터리에 test_data.txt 파일을생성하고, 다음프로그램을실행시켜보자. #include <stdio.h> #define SIZE 3 int main() double weight; int age, i; FILE *fp; fp = fopen("test_data.txt", "r"); main.c test_data.txt 파일내용 : ( 메모장사용해서만듦 ) 소스프로그램파일 (main.c) 이있는디렉터리에 test_data.txt 파일을저장 for (i = 0; i < SIZE; i++) fscanf(fp, "%lf %d", &weight, &age); printf("%.2f %d\n", weight, age); 실행결과 fclose(fp); return 0; 7 1) 파일입출력개요 FILE 포인터선언 FILE *fp 파일열기 fopen() 파일을읽거나파일에쓰기 파일입력함수들 : fgetc(), fgets(), fscanf(), fread() 파일출력함수들 : fputc(), fputs(), fprintf(), fwrite() 파일닫기 fclose() 8
목차 1) 파일입출력개요 2) 파일입출력절차 3) 텍스트파일 vs. 이진파일 4) 텍스트파일의입출력함수 5) 이진파일의입출력함수 ( 심화내용 ) 6) 기타파일입출력관련함수 ( 심화내용 ) 9 2) 파일입출력절차 파일입출력을위해서는 <stdio.h> 파일을반드시포함해야함 파일포인터 (file pointer) 선언 파일포인터 : FILE 구조체를가리키는포인터 FILE 구조체에대한포인터변수를선언하여사용 형식 FILE * 파일포인터명 ; 대문자!! 10
2) 파일입출력절차 파일열기 : fopen() 함수 해당파일에대한입출력스트림형성을요청하는기능의함수 해당파일을위한스트림을사용할수있도록파일포인터를반환 함수원형 FILE *fopen(char *filename, char *filemode); 함수인자 filename filemode 스트림을형성할파일이름 형성할스트림의종류 반환값 파일열기에성공 FILE 포인터를반환 파일열기에실패 NULL 을반환 11 2) 파일입출력절차 함수인자 filename (1/3) fopen() 함수가개방할파일을찾는기본위치 실행방법, 실행환경및설정에따라개방할파일이있는위치는다를수있음 특정한위치를지정하지않는경우 현재작업디렉터리 현재작업디렉터리 = 현재작업하고있는소스프로그램이위치한디렉터리 예 ) fopen("test.dat", "filemode"); 큰따옴표내에, 해당파일명만작성해주면됨! 12
2) 파일입출력절차 함수인자 filename (2/3) 개방할파일이현재작업디렉터리에존재하지않으면 경로를함께표기! 절대경로표기 드라이브명과디렉터리경로를포함하는방식 실행하는컴퓨터환경과상관없이경로는절대로변경되지않음 예 ) fopen("c:\\c_pro\\project\\test.dat", "filemode");» C 드라이브의하위디렉터리인 C_pro, 이디렉터리의하위디렉터리인 Project, 이디렉터리내에 test.dat 파일이존재» \\: \ 자체를디렉터리를나타내는기호로사용하기위해서는역슬래쉬 (\) 를두번사용해야함 13 2) 파일입출력절차 함수인자 filename (3/3) 상대경로표기 실행하는컴퓨터환경에따라경로가바뀜 현재작업디렉터리기준으로상대경로를지정 예 ) 그림 1 에서현재작업디렉터리 : src fopen("lib\\data.txt", "filemode"); fopen("..\\sys\\data2.txt", "filemode"); src C: sys lib < 그림 1 > 14
2) 파일입출력절차 함수인자 filemode 개방할파일의용도에따라적합하게지정해야함 적합한모드지정은파일을잘못사용하는것을막을수있음 < 파일접근방식에따른모드구분 > 구분모드의미기능 파일입력 r 읽기 (read) 읽기전용으로엶 파일을열수없는경우 NULL 을반환 파일출력 w a 쓰기 (write) 추가 (append) 쓰기전용으로엶 파일이없는경우 새로빈파일을생성 같은이름의파일이있는경우 내용을삭제하고새로운내용으로파일을생성 추가쓰기모드로엶 파일이없는경우 새로빈파일을생성 같은이름의파일이있는경우 기존파일의마지막부분에내용을추가 15 2) 파일입출력절차 fopen() 함수사용예 FILE *fp; fp = fopen("abc.txt", "w"); //FILE 구조체포인터 //abc.txt 파일을쓰기모드로개방 FILE *fp2; fp2 = fopen("data/text.dat", "a"); // 현재작업디렉터리의하위디렉터리인 data 내 text.dat 파일을추가모드로개방 16
2) 파일입출력절차 fopen() 함수사용시주의사항 fopen() 함수호출시, 이함수의반환값을반드시검사하여 파일이정상적으로열렸는지확인해야함 FILE *fp; fp = fopen("data.txt", "r"); if (fp == NULL) printf("couldn t open file!"); return -1; 17 2) 파일입출력절차 파일닫기 : fclose() 함수 해당파일로의입출력을위한스트림을닫음 운영체제가할당한자원의반환 버퍼링되었던데이터를출력 함수원형 int fclose(file *fp); 함수인자 fp 파일포인터변수명 반환값 파일닫기에성공 0을반환 파일닫기에실패 EOF 를반환 EOF (End Of File) 란? 파일의끝을표현하기위해정의해놓은상수 ( 즉, -1) 에러가발생했는지또는파일데이터를모두읽었는지확인할때사용 18
2) 파일입출력절차 fclose() 함수사용예 FILE *fp; fp = fopen("test.dat", "r"); if (fp == NULL) printf(" 파일열기에실패했습니다!\n"); return -1; fclose(fp); printf(" 파일닫기에성공했습니다!\n"); 19 2) 파일입출력절차 파일입출력절차연습 text1.txt 파일을읽기모드로열고닫기 현재작업디렉터리의상위디렉터리인 DATA 내에존재하는 data1.dat 파일을쓰기모드로열고닫기 현재작업디렉터리의하위디렉터리인 Project 내에존재하는 text2.dat 파일을추가모드로열고닫기 20
2) 파일입출력절차 참고 ) 표준입출력스트림 : 자동생성 FILE 포인터이름 스트림 의미 stdin 표준입력스트림 키보드로부터입력받음 stdout 표준출력스트림 모니터로결과출력 stderr 표준오류출력스트림 모니터로오류메시지출력 21 목차 1) 파일입출력개요 2) 파일입출력절차 3) 텍스트파일 vs. 이진파일 4) 텍스트파일의입출력함수 5) 이진파일의입출력함수 ( 심화내용 ) 6) 기타파일입출력관련함수 ( 심화내용 ) 22
파일저장방식에따른구분 3) 텍스트파일 vs. 이진파일 특성 텍스트 (text) 파일 사람이인식할수있는문자를담고있는파일 특별한응용프로그램없이도내용을볼수있는파일 메모장프로그램을통해파일을열었을때, 읽을수있는문자들로표현됨 모든데이터가문자열로변환되어기록됨 순차처리방식 이진 (binary) 파일 컴퓨터가인식할수있는데이터를담고있는파일 특정응용프로그램을이용해야액세스할수있는파일 메모장프로그램을통해파일을열었을때, 알아볼수없는이상한문자들로표현됨 수치데이터가문자로변환되지않고곧바로수치로저장 텍스트파일보다저장공간을적게차지 읽고쓰기가빠름 바이트단위의연속된데이터집합인블록단위로데이터를저장 임의접근처리방식 23 3) 텍스트파일 vs. 이진파일 fopen() 함수인자 filemode (1/3) 1 파일접근방식에따른모드구분 (p. 16 참조 ) 2 파일저장방식에따른모드구분 특성 텍스트 (text) 모드 텍스트파일의입출력시에사용 운영체제마다개행표현방식이다른데, 이를자동으로변환해줌 개발자는개행문자의변환을신경쓸필요가없음 운영체제에따른표현차로인한변환이발생함 이진 (binary) 모드 이진파일의입출력시에사용 파일에저장될때도이진형식으로표현된내용이그대로파일에저장 행으로분리되지않으므로행의끝을표시할필요가없음 널문자나개행문자같은글자들도데이터로취급 숫자로만이루어진데이터를파일에저장할경우이진모드가더효율적임 24
3) 텍스트파일 vs. 이진파일 fopen() 함수인자 filemode (2/3) 텍스트모드 r (rt) w (wt) a (at) 이진모드 rb wb ab 기능 읽기전용으로엶 파일을열수없는경우 NULL을반환 쓰기전용으로엶 파일이없는경우 새로빈파일을생성 같은이름의파일이있는경우 내용을삭제하고새로운내용으로파일을생성 추가쓰기모드로엶 파일이없는경우 새로빈파일을생성 같은이름의파일이있는경우 기존파일의마지막부분에내용을추가 25 3) 텍스트파일 vs. 이진파일 fopen() 함수인자 filemode (3/3) 텍스트모드 이진모드 r+ rb+ w+ wb+ a+ ab+ 기능 파일을읽기와쓰기모드로엶 반드시파일이존재해야함 파일을읽기와쓰기모드로엶 파일이없는경우 새로빈파일을생성 같은이름의파일이있는경우 내용을삭제하고새로운내용으로파일을생성 파일을읽기와추가모드로엶 파일이없는경우 새로빈파일을생성 같은이름의파일이있는경우 읽기는임의의위치에서가능하나, 쓰기는파일의끝에서만가능 26
3) 텍스트파일 vs. 이진파일 텍스트모드를사용한 fopen() 함수사용예 FILE *fp; fp = fopen("test.txt", "r"); //FILE 구조체포인터 //test.txt 파일을읽기모드로개방 이진모드를사용한 fopen() 함수사용예 FILE *fp; fp = fopen("test.dat", "rb"); //FILE 구조체포인터 //test.dat 파일을이진읽기모드로개방 27 파일입출력함수 3) 텍스트파일 vs. 이진파일 처리대상처리단위파일입력파일출력 문자 fgetc() fputc() 텍스트파일 문자열 fgets() fputs() 지정형식 fscanf() fprintf() 이진파일블록 fread() fwrite() C 언어에서는위의파일입출력함수를라이브러리함수 (stdio.h) 로제공 28
3) 텍스트파일 vs. 이진파일 파일입출력함수 파일입력함수를사용하기위한 fopen() 함수인자설정 파일이름 : 읽을파일의이름 파일모드 ( 읽기모드 ) 텍스트파일 : "r" 이진파일 : "rb" 파일출력함수를사용하기위한 fopen() 함수인자설정 파일이름 : 출력할파일의이름 파일모드 ( 쓰기혹은추가모드 ) 텍스트파일 : "w" 혹은 "a" 이진파일 : "wb" 혹은 "ab" 29 목차 1) 파일입출력개요 2) 파일입출력절차 3) 텍스트파일 vs. 이진파일 4) 텍스트파일의입출력함수 5) 이진파일의입출력함수 ( 심화내용 ) 6) 기타파일입출력관련함수 ( 심화내용 ) 30
4) 텍스트파일입출력함수 지정형식단위의파일입력함수 : fscanf() 형식을지정하여파일의데이터를읽기위한함수 여러형태의자료들 ( 정수, 문자, 문자열등 ) 을한번에입력가능 함수의첫번째인자로파일포인터가사용된다는것을제외하고는 scanf() 함수와사용법이동일함 함수원형 int fscanf(file *fp, char *format, arg1, arg2, ); 함수인자 fp format arg1, arg2, 파일포인터변수명 형식제어문자열 입력하고자하는변수리스트 반환값 성공 입력한변수의개수를반환 파일의끝이거나오류발생 EOF를반환 31 4) 텍스트파일입출력함수 fscanf() 함수사용예 char str[10]; int num; FILE *fp = fopen("data.txt", "r"); if (fp == NULL) printf("couldn t open file!"); return -1; fscanf(fp, "%s %d", str, &num); fp에연결된 data.txt 파일로부터문자열과정수를읽어와서각각 str 배열과 num에저장 32
4) 텍스트파일입출력함수 지정형식단위의파일출력함수 : fprintf() 형식을지정하여파일에데이터를쓰기위한함수 함수의첫번째인자로파일포인터가사용된다는것을제외하고는 printf() 함수와사용법이동일함 함수원형 int fprintf(file *fp, char *format, arg1, arg2, ); 함수인자 fp format arg1, arg2, 파일포인터변수명 형식제어문자열 출력하고자하는변수리스트 반환값 성공 출력한데이터의바이트수 실패 / 오류발생 음수를반환 33 4) 텍스트파일입출력함수 fprintf() 함수사용예 int age = 25; FILE *fp = fopen("data.txt", "w"); if (fp == NULL) printf("couldn t open file!"); return -1; fprintf(fp, " 나이 : %d세", age); fprintf(stdout, " 나이 : %d 세 ", age); // printf(" 나이 : %d 세 ", age); fp 에연결된 data.txt 파일과모니터에동일하게 " 나이 : 25 세 " 가출력됨 34
4) 텍스트파일입출력함수 문자단위의파일입력함수 : fgetc() 문자한개를파일로부터읽기위한함수 함수원형 int fgetc(file *fp); 함수인자 fp 파일포인터변수명 성공 파일로부터읽은문자를반환반환값 파일의끝에도달하거나오류발생 EOF를반환 문자단위의파일출력함수 : fputc() 문자하나를파일에쓰기위한함수 함수원형 int fputc(int char, FILE *fp); 함수인자 char fp 출력하고자하는문자상수또는변수 파일포인터변수명 반환값 성공 출력하는문자 char 를반환 실패 / 오류발생 EOF 를반환 35 4) 텍스트파일입출력함수 fgetc() 함수의수행과정 fgetc() 함수 한문자씩만가져감! 버퍼로부터의입력위치는 FILE 구조체의멤버인 파일위치지시자 로부터알수있음 FILE 구조체와연결되어있는버퍼 X Y Z P 파일위치지시자 fgetc( ) 함수가처음호출될때, 이미모든데이터는버퍼에저장됨! data.txt fputc() 함수의수행과정 fgetc() 함수와마찬가지로버퍼를사용함 한문자를출력할때마다일단버퍼에출력하고, 개행문자가출력되면하드디스크로파일을출력함 36
4) 텍스트파일입출력함수 문자단위의파일입출력함수연습 #include <stdio.h> int main() FILE *fp1, *fp2; char ch; fp1 = fopen("input.txt", "r"); if (fp1 == NULL) printf("couldn t open file!"); return 1; fp2 = fopen("output.txt", "w"); if (fp2 == NULL) printf("couldn t open file!"); return 1; while((ch = fgetc(fp1))!= EOF) printf("%c", ch); fputc(ch, fp2); fclose(fp1); fclose(fp2); return 0; 37 4) 텍스트파일입출력함수 문자열단위의파일입력함수 : fgets() 파일에쓰여진문자열을읽는데사용하는함수 파일에쓰여진개행문자까지문자열에포함 한번에읽을수있는문자열의길이가정해져있음 한번에읽을수있는문자열 = ( 최대입력문자수 1) 개의문자 + 널문자 한번에읽을수있는문자열내에, 개행문자가포함되어있다면 개행문자까지의문자열을반환함 38
4) 텍스트파일입출력함수 문자열단위의파일입력함수 : fgets() 함수원형 char *fgets(char *s, int n, FILE *fp); 함수인자 s n fp 파일로부터읽을문자열을저장할포인터 읽을문자열의최대길이 파일포인터변수명 반환값 성공 문자열 s를반환 파일의끝에도달하거나실패 / 오류발생 NULL 을반환 39 4) 텍스트파일입출력함수 fgets() 함수사용예 char str1[20], str2[20], str3[20]; FILE *fp = fopen("info.txt", "r"); 1) fgets(str1, 20, fp); info.txt Neungdong ro, Gwangjin gu, Seoul, Korea. N e u n g d o n g - r o, \n \0 20 개의문자를읽기전에개행문자를읽으므로뒤에널문자를합쳐 str1 배열에저장 2) fgets(str2, 20, fp); G w a n g j i n - g u, S e o u l \0 19 개의문자를읽은후뒤에널문자를합쳐 str2 배열에저장 3) fgets(str3, 20, fp);, K o r e a. \n \0 이전에읽은곳다음부터읽다가 20 개의문자를읽기전에개행문자를읽게되어, 그뒤에널문자를합쳐 str3 배열에저장 40
4) 텍스트파일입출력함수 문자열단위의파일출력함수 : fputs() 문자열을파일에쓰기위한함수 문자열의끝을나타내는널문자는파일에쓰지않으며, 그뒤에개행문자도자동으로들어가지않음 함수원형 int fputs(char *str, FILE *fp); 함수인자 str fp 출력하고자하는문자열상수또는변수 파일포인터변수명 반환값 성공 출력한바이트수를반환 실패 / 오류발생 EOF 를반환 41 4) 텍스트파일입출력함수 문자열단위의파일입출력함수연습 #include <stdio.h> int main() char str[100]; FILE *fp1, *fp2; fp1 = fopen("input.txt", "r"); if (fp1 == NULL) printf("couldn t open file!"); return 1; fp2 = fopen("output.txt", "w"); if (fp2 == NULL) printf("couldn t open file!"); return 1; while(fgets(str, sizeof(str), fp1)!= NULL) printf("%s", str); fputs(str, fp2); fclose(fp1); fclose(fp2); return 0; 42
4) 텍스트파일입출력함수 파일의끝 " 확인하는방법 1 반환값참조 함수 fgetc() fgets() fscanf() 방법파일끝에서 EOF(-1) 반환파일끝에서 NULL(0) 반환파일끝에서 EOF(-1) 반환 2 feof() 함수사용 43 feof() 함수 4) 텍스트파일입출력함수 파일의끝까지데이터를모두읽어들인상태인지를확인하는함수 이함수를사용하기위해서는 <stdio.h> 를포함시켜야함 함수원형 int feof(file *fp); 함수인자 fp 파일포인터변수명 반환값 파일의끝이면 0이아닌값을반환 파일의끝이아니면 0 를반환 EOF vs. feof() 함수 모든파일의끝에는 EOF 가존재 EOF 는파일의한부분임 feof() 함수는 EOF 를만났을때 0 을반환! 44
feof() 함수사용시, 주의사항 4) 텍스트파일입출력함수 예1) data.txt 파일을빈파일로하여, 다음프로그램을실행시켜보자. 결과는? #include <stdio.h> int main() FILE *fp; char str[100]; fp = fopen("data.txt", "r"); if (fp == NULL) printf("couldn t open file!"); return 1; while(!feof(fp)) fgets(str, sizeof(str), fp); printf("%s", str); fclose(fp); return 0; 45 4) 텍스트파일입출력함수 feof() 함수사용시, 주의사항 예2) 다음과같은내용의 data.txt 파일을생성하고, 앞의프로그램을실행시켜보자. 결과는? <data.txt 파일내용 > < 실행결과 > 46
4) 텍스트파일입출력함수 feof() 함수사용시, 주의사항 앞의예들의원인 마지막데이터뒤에는파일의끝을나타내는특수문자 (^Z) 가시스템에의해자동으로들어감 빈파일의경우에도 ^Z가존재함 ( 예1) ^Z의위치문제 ( 예2) feof(fp) 함수반환값 = 0( 거짓 ) ^Z를지나가야 feof(fp) 함수는 0이아닌값 ( 참 ) 을반환함 해결방법 먼저데이터를읽은후, 파일의끝에도달했는지를확인하도록함 47 4) 텍스트파일입출력함수 feof() 함수사용시, 주의사항 앞의문제들을해결한수정된코드 fgets(str, sizeof(str), fp); #include <stdio.h> while(!feof(fp)) int main() printf("%s", str); FILE *fp; fgets(str, sizeof(str), fp); char str[100]; fclose(fp); fp = fopen("data.txt", "r"); if (fp == NULL) return 0; printf("couldn t open file!"); return 1; < 예제2 실행결과 > < 예제 1 실행결과 > 48
목차 1) 파일입출력개요 2) 파일입출력절차 3) 텍스트파일 vs. 이진파일 4) 텍스트파일의입출력함수 5) 이진파일의입출력함수 ( 심화내용 ) 6) 기타파일입출력관련함수 ( 심화내용 ) 49 5) 이진파일입출력함수 ( 심화내용 ) 블록단위의파일입출력함수 이진파일을대상으로함 한번에지정한크기의블록단위로데이터를파일로부터읽거나쓰고자할때사용 블록 (block): 바이트단위의연속된데이터집합 구조체와같이일정한크기의데이터를입출력해야할때, 주로사용됨 fread() 함수와 fwrite() 함수가있음 50
5) 이진파일입출력함수 ( 심화내용 ) 이진파일입력함수 : fread() 이진파일에서데이터블록을읽기위한함수 함수원형 함수인자 반환값 의미 unsigned int fread(void *ptr, unsigned int size, unsigned int n, FILE *fp); ptr 파일로부터읽은데이터를기억시킬버퍼의시작주소 size 읽을데이터의바이트수 ( 블록의크기 ) n size 만큼읽기위한반복횟수 ( 블록의개수 ) fp 파일포인터변수명 성공 파일로부터읽은블록의개수 n 을반환 파일의끝혹은실패 n 보다작은값을반환 이진파일에서 (size * n) 바이트의데이터를읽어버퍼에저장한후, 읽은블록개수를반환 51 5) 이진파일입출력함수 ( 심화내용 ) fread() 함수사용예 int height, age[10]; FILE *fp = fopen("data.bin", "rb"); fread(&height, sizeof(int), 1, fp); fp에연결된이진파일에서 int형크기의블록 1개를읽어서변수 height의메모리에씀 즉, 파일에서 1개의정수를읽어서 height 변수에저장 fread(age, sizeof(int), 10, fp); fp에연결된이진파일에서 int형크기의블록 10개를읽어서 age ( 배열의시작주소 ) 번지의메모리에저장 즉, 파일에서 10개의정수를읽어서 age 배열에저장 52
5) 이진파일입출력함수 ( 심화내용 ) 이진파일출력함수 : fwrite() 이진파일에데이터블록을쓰기위한함수 함수원형 함수인자 반환값 의미 unsigned int fwrite(const void *ptr, unsigned int size, unsigned int n, FILE *fp); ptr 파일에기록하려는데이터가있는버퍼의시작주소 size 파일에출력하는데이터의바이트수 ( 블록의크기 ) n size 만큼쓰기위한반복횟수 ( 블록의개수 ) fp 파일포인터변수명 성공 파일에출력한블록의개수 n 을반환 실패 n 보다작은값을반환 버퍼에저장된 (size * n) 바이트의데이터를이진파일에출력한후, 출력한블록개수를반환 53 5) 이진파일입출력함수 ( 심화내용 ) fwrite() 함수사용예 Int height, age[10]; FILE *fp = fopen("data.bin", "wb"); fwrite(&height, sizeof(int), 1, fp); 변수 height 메모리에서 int형크기의블록 1개를읽어서 fp에연결된이진파일에씀 즉, height 변수에서 1개의정수를읽어서 data.bin 파일에저장 fwrite(age, sizeof(int), 10, stdout); age 배열에서 int형크기의블록 10개를읽어서표준출력장치인모니터로출력 즉, age 배열에서 10개의정수를읽어모니터에출력 54
5) 이진파일입출력함수 ( 심화내용 ) 이진파일입출력함수연습 #include <stdio.h> struct person char name[8]; int age; data[10]="tom",46, "James",33, "Jane",21; void main() FILE *fp; struct person buf[10]; int i; fp=fopen("data.txt", "w"); fwrite(data, sizeof(struct person), 3, fp); fclose(fp); fp=fopen("data.txt", "r"); fread(buf, sizeof(struct person), 3, fp); for(i=0; i<=2; i++) printf("i=%d %s %d\n", i, buf[i].name, buf[i].age); fclose(fp); 55 목차 1) 파일입출력개요 2) 파일입출력절차 3) 텍스트파일 vs. 이진파일 4) 텍스트파일의입출력함수 5) 이진파일의입출력함수 ( 심화내용 ) 6) 기타파일입출력관련함수 ( 심화내용 ) 56
6) 기타파일입출력관련함수 ( 심화내용 ) 파일의임의접근처리방식 이진파일을대상으로함 파일의임의의위치에서바로읽기 / 쓰기를할수있는접근방식 파일읽기 / 쓰기를시작할위치를가리키는포인터인파일위치지시자를조작하는함수를사용 파일위치지시자 : 파일에서다음에읽거나쓸데이터의위치를나타냄 fseek(), rewind(), ftell() 함수사용가능 이함수들을이용하면이진파일에대해임의의블록을곧바로찾아가서읽거나블록을수정하는작업이가능 이함수들을사용하기위해서는 <stdio.h> 파일을포함시켜야함 57 6) 기타파일입출력관련함수 ( 심화내용 ) fseek() 함수 (1/2) 파일위치지시자를지정한위치로이동시킬수있는함수 fp에연결된파일의파일위치지시자가 origin으로부터 offset만큼떨어진곳을가리키게함 다음에읽기 / 쓰기를시작할위치를 (origin + offset) 바이트위치로변경함 origin 값 : 상수로정의된 SEEK_SET(0), SEEK_CUR(1), SEEK_END(2) 중하나를사용 58
6) 기타파일입출력관련함수 ( 심화내용 ) fseek() 함수 (2/2) 함수원형 int fseek(file *fp, long int offset, int origin); fp 파일포인터변수명 함수인자 반환값 offset origin 성공 0을반환 실패 0이아닌값을반환 origin 으로부터이동할바이트수 - 양수 (+): 순방향 ( 기준점이후 ) - 음수 (-): 역방향 ( 기준점이전 ) offset 을적용할기준점 - SEEK_SET(0): 파일의맨처음위치 - SEEK_CUR(1): 파일에서의현재위치 - SEEK_END(2): 파일의맨끝위치 59 6) 기타파일입출력관련함수 ( 심화내용 ) fseek() 함수사용예 fseek(fp, 10, SEEK_SET); 다음읽기 / 쓰기위치를파일시작지점에서 10바이트이후로이동 fseek(fp, 20, SEEK_CUR); 다음읽기 / 쓰기위치를현재위치에서 20바이트이후로이동 fseek(fp, -20, SEEK_END); 다음읽기 / 쓰기위치를파일의끝지점에서 20바이트이전으로이동 0 10 40 60 80 100 fseek(fp, 10, 0) 현재파일위치 fseek(fp, 20, 1) fseek(fp, -20, 2) 지시자의위치 60
6) 기타파일입출력관련함수 ( 심화내용 ) rewind() 함수 파일위치지시자를파일의시작지점으로이동시키는함수 fseek(fp, 0, SEEK_SET) 와동일한효과 함수원형 void rewind(file *fp) 함수인자 fp 파일포인터변수명 61 6) 기타파일입출력관련함수 ( 심화내용 ) ftell() 함수 현재파일위치지시자가가리키는곳의위치를반환하는함수 즉, 현재파일위치지시자가가리키는곳이파일의시작위치로부터몇바이트떨어져있는지를알려줌 가정사항 ) 파일의시작위치를상대적위치 0으로간주함! 함수원형 long ftell (FILE *fp); 함수인자 fp 파일포인터변수명 반환값 성공 읽기 / 쓰기위치를반환 실패 / 오류 -1 을반환 62
6) 기타파일입출력관련함수 ( 심화내용 ) fseek() 함수와 ftell() 함수사용예 #include <stdio.h> int main() FILE *fp; int size; fp = fopen("data.txt", "rb"); if (fp == NULL) printf("couldn t open file!"); return 1; fseek(fp, 0, SEEK_END); size = ftell(fp); fclose(fp); printf("size of the file: %d bytes.\n", size); return 0; 63 6) 기타파일입출력관련함수 ( 심화내용 ) 일반적으로, 파일버퍼내의데이터가파일에출력되는시점 1버퍼가다찼을때 2 파일이닫힐때 3 프로그램이종료될때 버퍼플러쉬 (buffer flush) 란? 필요에의해버퍼의내용을강제로파일에출력하고, 버퍼를비우는일을말함 fflush() 함수사용 이함수를사용하기위해서는 <stdio.h> 파일을포함시켜야함 함수원형 int fflush(file *fp); 함수인자 fp 파일포인터변수명 예 fflush(stdout) 출력버퍼안에존재하는데이터들은즉시출력됨 64
6) 기타파일입출력관련함수 ( 심화내용 ) fflush() 함수사용예 #include <stdio.h> char mybuf[30]; int main() FILE *fp; fp = fopen("data.txt", "r+"); if (fp == NULL) printf("couldn t open file!"); return 1; fputs("remove data (fflush) ", fp); fflush(fp); fgets(mybuf, 30, fp); puts(mybuf); fclose(fp); return 0; 65