C Programming 파일입출력 Seo, Doo-okok clickseo@gmail.com http://www.clickseo.com
목 차 파일입출력 파일입출력함수 파일처리함수 2
파일입출력 파일입출력 파일의이해 파일입출력의이해 파일입출력함수 파일처리함수 3
파일의이해 파일 (File) 하나의단위로취급해야하는데이터들의외부적컬렉션 파일의종류 텍스트파일 : 모든데이터가그래픽문자로저장 ( 라인단위로구성 ) 이진파일 : 데이터가정수혹은부동소수점숫자와같은컴퓨터내부표현형식으로저장 저장장치 4
텍스트파일과이진파일 파일의이해 (cont d) 텍스트파일 ( 텍스트모드 ) 로읽은경우 48 65 6C 6C 6F 0A 이진파일 ( 이진모드 ) 로읽은경우 48 65 6C 6C 6F 0D 0A 1A H e l l o CR LF ^z 48 65 6C 6C 6F 0D 0A 1A 저장장치 이진모드로읽으면 CR 과 LF, 그리고 Ctrl-z 도단순한데이터로취급하여그대로읽혀진다. 5
시스템콜 (System Call) 파일입출력의이해 open() user application user mode kernel mode system call interface i open() system call 의구현... return 6
FILE 구조체 파일입출력의이해 (cont d) 파일또는텍스트스트림에관한정보를저장하는구조체 파일이름, 파일버퍼의위치, 파일의현재상태등의정보를가지고있다. 입출력처리를위해포함 : <stdio.h> #ifndef _FILE_DEFINED struct _iobuf char *_ptr; // 파일포인터 : 파일의현재위치 int _cnt; // 입력버퍼에서사용할수있는문자개수 char *_base; // 메모리상에있는파일원형의주소 int _flag; // 파일포인터가파일의끝에오면제5비트가 1이된다. int _file; // 파일식별자 int _charbuf; // 문자열버퍼 int _bufsiz; // 버퍼의크기 char *_tmpfname; // 임시파일이름의위치 ; typedef struct _iobuf FILE; #define _FILE_DEFINED #endif 7
파일입출력의이해 (cont d) 파일열기 : fopen 외부파일과프로그램사이에연결을만든다. 파일테이블을생성하여파일처리에필요한정보를저장한다. FILE *fopen(const char *filename, const char *mode); filename : 대상파일의경로를포함한이름 mode : 파일의열기모드 ( 대상파일이없거나오류가발생한다면 NULL 을반환 ) FILE *fp; if (( fp = fopen( data.txt, w )) == NULL) printf( 파일개방실패!!! \n ); exit(1); 8
파일입출력의이해 (cont d) 파일열기 (cont d) fopen 함수의파일열기모드 : 텍스트모드 (text mode) 모드의미비고 r w a r+ 읽기전용 (Read Only) 파일이없으면 NULL을반환쓰기전용 (Write Only) 파일이존재하지않으면새파일을생성기존파일이있으면그내용은무시하고처음부터새로쓴다. 추가모드 (Append Only) 파일이존재하지않으면새파일을생성기존파일이있으면기존파일의끝에추가만가능하다. 기존파일에대한읽기와쓰기가모두가능하도록파일개방파일이없으면 NULL 을반환 쓰기불가읽기불가읽기불가읽기 + 쓰기 w+ 무조건새로운파일을생성하여읽기와쓰기가가능하도록파일을연다. 읽기 + 쓰기 a+ 기존파일의끝에서부터읽기와쓰기가가능하도록파일을열고, 파일이 없으면새로생성한다. 이전부분은 쓰기불가 9
파일입출력의이해 (cont d) 파일열기 (cont d) fopen 함수의파일열기모드 : 이진모드 (binary mode) 모드 의미 rb, wb, ab 이진모드로파일을개방하고텍스트모드에서의 r, w, a 와같은의미 r+b, rb+ w+b, wb+ 이진모드로파일을개방하고텍스트모드에서의 r+, w+, a+ 와동일한의미 a+b, ab+ 10
파일입출력의이해 (cont d) 파일닫기 : fclose 파일을더이상사용할필요가없을경우에는파일을닫아서버퍼공간과같은시스템자원을반납하여야한다. int fclose(file *stream); #include <stdio.h> 호출성공 : 0 을반환호출실패 : EOF 를반환 int main(void) FILE *fp;... fp = fopen( test.txt, w );... fclose(fp); 11
파일입출력의이해 (cont d) 전형적인파일처리작업형태 #include <stdio.h> int main(void) FILE *fpin, *fpout; if (fpin = fopen( source.txt, r )) == NULL)... // 에러처리코드 if (fpout = fopen( copy.txt, w )) == NULL)...... // 대상파일에대한읽고쓰는작업을수행 fclose(fpin); f fclose(fpout); return 0; 12
파일입출력개념 파일입출력함수 파일입출력함수 문자입출력함수 : fgetc, fputc 문자열입출력함수 : fgets, fputs 서식화된파일입출력함수 : fscanf, fprintf 이진파일입출력함수 : fread, fwrite 파일처리함수 13
파일입출력함수 문자입출력함수 : fgetc, fputc 파일에서한문자 (1 바이트 ) 씩읽는함수 #include <stdio.h> int fgetc (FILE *stream); 반환 ( 성공 ) : 읽어들인한문자의 byte를 int 형으로반환 ( 실패또는파일의끝을만나면 ) : EOF 를반환 파일에한문자 (1 바이트 ) 씩쓰는함수 #include <stdio.h> int fputc (int ch, FILE *stream); 반환 ( 성공 ) : 기록한문자를 int 형으로반환 ( 실패 ):EOF 를반환 14
파일입출력함수 (cont d) 문자입출력함수 : ungetc 지정된문자를입력스트림에되돌려놓는다 (getc 함수와반대동작 ). 이스트림을다음에읽으면지금되돌려진문자가반환될것이다. #include <stdio.h> int ungetc (int ch, FILE *stream); ch = getc(stdin); if (isdigit(ch)) else ungetc(option, stdin);... 15
파일입출력함수 (cont d) 프로그램예제 : fputc 함수를사용하여데이터를파일에저장 #include <stdio.h> #include <stdlib.h> int main(void) char FILE ch; *fpout; fpout = fopen("data.txt", "w"); if (fp == NULL) printf("data.txt 파일개방실패!!! \n"); exit(100); printf(" 저장할문장입력 ( 종료 : Ctrl + Z)... \n"); while ((ch = getchar())!= EOF) fputc(ch, fpout); 파일에출력 fclose(fpout); return 0; 16
파일입출력함수 (cont d) 프로그램예제 : fgetc 함수를사용하여데이터를파일에서읽기 #include <stdio.h> #include <stdlib.h> int main(void) char FILE ch; *fpin; fpin = fopen("data.txt", r"); if (fp == NULL) printf("data.txt 파일개방실패!!! \n"); exit(100); 파일에서읽기 printf( ### 파일내용 ### \n"); while ((ch = fgetc(fpin))!= EOF) putchar(ch); fclose(fpin); return 0; 17
파일입출력함수 (cont d) 문자열입출력함수 : fgets, fputs 파일에서문자열단위로입력을수행하는함수 #include <stdio.h> char *fgets (char *str, int n, FILE *stream); 반환 ( 성공 ) : str의주소를반환 ( 실패 ) : NULL 을반환 파일에서문자열단위로출력을수행하는함수 #include <stdio.h> int fputs(char *str, FILE *stream); 반환 ( 성공 ) : 음수가아닌정수를반환 ( 실패 ) : EOF 를반환 18
파일입출력함수 (cont d) 프로그램예제 : fgets 와 fputs 을이용한타자기프로그램 #include <stdio.h> #include <stdlib.h> int main(void) char FILE str[1024]; *fpout; if (!(fpout = fopen ( data data.txt txt", "w"))) printf( data.txt 파일개방실패!!! \n"); exit (100); 파일에출력 while ( fgets (str, sizeof (str), stdin) ) fputs (str, fpout); fclose (fpout); return 0; 19
파일입출력함수 (cont d) 서식화된파일입출력함수 : fscanf, fprintf 파일을대상으로서식화된입력기능을지원하는함수 #include <stdio.h> int fscanf(file *stream, const char *format, 가변길이인수리스트 ); 반환 ( 성공 ) : 정수를반환 ( 실패 ) : EOF 를반환 파일을대상으로서식화된출력기능을지원하는함수 #include <stdio.h> int fprintf(file *stream, const char *format, 가변길이인수리스트 ); 반환 ( 성공 ) : 정수를반환 ( 실패 ) : EOF 를반환 20
파일입출력함수 (cont d) 프로그램예제 : 텍스트파일에서학생성적을읽어들여출력 #include <stdio.h> #include <stdlib.h> int main(void) char name[10]; int kor, eng, math, tot; double ave; FILE *fpin; 파일내용읽기 if (!(fpin = fopen ("data.txt", "r"))) printf("data.txt 파일개방실패!!! \n"); exit (100); while ( fscanf(fpin, "%s %d %d %d", name, &kor, &eng, &math) == 4) tot = kor + eng + math; ave = tot / 3.0; printf("%10s %3d %3d %3d %5d %8.2f \n", name, kor, eng, math, tot, ave); fclose(fpin); return 0; 21
파일입출력함수 (cont d) 이진파일입출력함수 : fread, fwrite fread 함수 : 이진모드로데이터를읽는함수 size_t fread(void *buffer, size_t size, size_t n, FILE *stream); 호출성공 : 블록의개수를반환 호출실패 : 0 을반환 fwrite 함수 : 이진모드로데이터를쓰는함수 size_t fwrite(void *buffer, size_t size, size_t n, FILE *stream); 호출성공 : 블록의개수를반환 (n) 호출실패 : n 이외의값을반환 buffer : 파일로부터읽어들인데이터를기억시킬버퍼를가리키는포인터 size : 한번에읽어들일수있는데이터의바이트수 n : size 만큼읽어들이기위해지정하는반복횟수 stream : 대상이되는파일포인터 22
파일입출력함수 (cont d) 프로그램예제 : fread 와 fwrite 를이용한블록입출력 (1/3) #include <stdio.h> #include <stdlib.h> #include <conio.h> typedef struct _score char name[12]; int kor, eng, math, tot; float ave; SCORE; char *file = "data.txt"; 23
파일입출력함수 (cont d) 프로그램예제 : fread 와 fwrite 를이용한블록입출력 (2/3) int main(void) int count; FILE *fp; SCORE temp; fp = fopen(file, "wb"); if(fp == NULL) printf(" 파일개방실패!!! \n"); exit(100); printf(" 이름 : "); gets(temp.name); printf(" 국어 : "); scanf("%d", &temp.kor); printf(" 영어 : "); scanf("%d", &temp.eng); printf(" 수학 : "); scanf("%d%*c", &temp.math); temp.tot tot = temp.kor + temp.eng eng + temp.math; math; temp.ave = (float)temp.tot / 3; fwrite(&temp, sizeof(score), 1, fp); fclose(fp); 24
파일입출력함수 (cont d) 프로그램예제 : fread 와 fwrite 를이용한블록입출력 (3/3) printf("\n> 저장된파일정보출력을원하면아무키나누르시오... "); getch(); fp = fopen(file, "rb"); if (fp == NULL) printf(" 파일개방실패!!! \n"); exit(200); count = fread(&temp, sizeof(score), 1, fp); if (count == 0) printf(" 파일에서정보읽기실패!!! \n"); else printf("\n\n%s %3d %3d %3d %5d %8.2f\n", temp.name, temp.kor, temp.eng, temp.math, temp.tot, temp.ave); fclose(fp); return 0; 25
파일처리함수 파일입출력개념 파일입출력함수 파일처리함수 랜덤액세스함수 : fseek, ftell 오류처리관련함수 기타함수 26
파일처리함수 랜덤액세스함수 : fseek, ftell fseek 함수 : 파일포인터 stream 을임의의위치로이동하는함수 원하는자료에대한직접접근 (direct access) 이가능 #include <stdio.h> int fseek(file *stream, long offset, int whence); stream : 대상이되는파일포인터 offset : whence 위치부터새로운위치까지상대적으로떨어진거리 ( 바이트단위 ) whence : 파일포인터이동을위한기준점 기준점 값 의미 SEEK_SET 0 파일의시작위치를기준으로파일포인터를이동하겠다는뜻 SEEK_CUR 1 현재의파일포인터위치를기준으로다음위치로이동시키겠다는뜻 SEEK_ END 2 파일의마지막위치를기준으로파일포인터를이동하겠다는뜻 27
파일처리함수 (cont d) 랜덤액세스함수 (cont d) ftell 함수 : 파일포인터의위치를얻어오는함수 첫시작위치부터현재 stream 위치까지의거리를 long 형으로알려준다. int ftell(file *stream); t 반환 ( 성공 ) : 파일의시작부터현재파일포인터까지의거리 ( 실패 ) : -1 을반환 28
오류처리관련함수 파일처리함수 (cont d) feof f 함수 : 파일의끝에도달했는지여부를알려주는함수 파일의끝을읽으면 0 이아닌수를반환하고, 그렇지않은경우는 0 을반환한다. int feof(file f(file *stream); t feof 함수의일반적인사용형식 while (!feof(fp)) // 파일의끝이아니라면 putchar(fgetc(fp)); // 한문자씩읽어서화면에바로출력 29
파일처리함수 (cont d) 오류처리관련함수 (cont d) ferror 함수 : 파일처리도중입출력오류가발생할때오류를알려주는함수 파일포인터 stream과관련된처리에입출력오류가없으면 0을반환하고, 그렇지않으면 0이아닌값을반환하여오류를알린다. int ferror(file *stream); 파일처리도중에발생할수있는상태 읽기오류 (read error) 쓰기오류 (write error) 파일끝 (end of file) clearerr 함수 : error 상태를 clear 하는함수 FILE 구조체의멤버중 flag 의 EOF Indicator 비트를 0 으로설정하고, ferror 함수가 설정해놓은 Error Indicator 비트도 0 으로만들어오류상태를되돌려놓는역할을 한다. void clearerror(file *stream); 30
파일처리함수 (cont d) 오류처리관련함수 (cont d) perror 함수 : 입출력오류가발생할경우에오류메시지를콘솔로출력 파일이없거나이미존재하는경우등다수의상황에따른오류코드를 error.h 에매크로상수로정의해두는데, 오류가발생할경우 errno 에자동으로저장된다. void perror(const char *errmsg); #include <errno.h> fp = fopen( perror perror.txt txt, r ); if (!fp) perror( Unable to open file for reading ); printf( errno = %d\n, errno ); 31
기타함수 : fflush 파일처리함수 (cont d) fflush 함수 : 대상이되는파일버퍼를비우는함수 int fflush(file *stream); Stream이 stdout인경우는입출력버퍼를비우고, stream가디스크파일스트림인경우는파일버퍼를비움으로써버퍼의내용을최종적으로디스크에기록한다. 작업이성공적일때는 0 을반환하고, 실패한다면 EOF 를반환 만약 stream 이 NULL 인경우라면모든디스크버퍼를비운다. 32
참고문헌 [1] 서두옥, 이동호 ( 감수 ), 또하나의 C : 프로그래밍은셀프입니다, 프리렉, 2011. [2] 윤성우, 열혈강의 C 프로그래밍, 프리렉, 2006, [3] 서현우, 뇌를자극하는 C 프로그래밍, 한빛미디어, 2005,. [4] 김일광, C 프로그래밍입문 : 프로그래밍을모국어처럼유창하게, 한빛미디어, 2004, [5] Behrouz A. Forouzan, Richard F. Gilberg, 김진외 7 인공역, 구조적프로그래밍기법을위한 C, 도서출판인 터비젼, 2004, [6] Brian W. Kernighan, Dennis M. Ritchie, 김석환외 2인공역, The C Programming Language : 2/e, 대영사, 2004, [7] SAMUEL P. HARBISON Ⅲ, GUY L. STEELE, C 프로그래밍언어, C : A Reference Manual 5/e, Pearson Education Korea, 2005. [8] Wikipedia, http://www.wikipedia.org/. 이강의자료는저작권법에따라보호받는저작물이므로무단전제와무단복제를금지하며, 내용의전부또는일부를이용하려면반드시저작권자의서면동의를받아야합니다. Copyright Clickseo.com. All rights reserved. 33