C Programming 파일처리 (File Processing) Seo, Doo-Ok Clickseo.com clickseo@gmail.com
목 차 파일입출력 텍스트파일입출력함수 이진파일입출력함수 다양한파일처리함수 2
파일입출력 파일입출력 입출력스트림 파일과파일입출력 텍스트파일입출력함수 이진파일입출력함수 다양한파일처리함수 3
스트림 (Stream) 데이터의논리적흐름 입출력스트림 (1/2) 개발자와하드웨어장치사이에존재하는추상적계층 하드웨어장치파일과연결되어데이터전송을중재 표준입출력스트림의종류 <stdio.h> 에입출력스트림정의 입출력스트림 기능 디바이스장치 stdin 표준입력 키보드 stdout 표준출력 모니터 stderr 표준오류 모니터 stdprn 표준프린터 프린터 (LPT1) stdaux 표준보조입출력 직렬포트 (COM1) 4
입출력스트림 입출력스트림 (2/2) 파일스트림 ( 파일포인터 ) 파일스트림 ( 파일포인터 ) 저장장치 stdout 저장장치 stdin 표준출력 입력장치 표준입력 stderr 표준오류 출력장치 프로그램 5
파일 (File) 파일과파일입출력 (1/9) 하나의단위로취급해야하는데이터들의외부적컬렉션 파일의종류 텍스트파일 : 모든데이터가그래픽문자로저장 ( 라인단위로구성 ) 이진파일 : 데이터가정수혹은부동소수점숫자와같은컴퓨터내부표현형식으로저장 저장장치 6
파일과파일입출력 (2/9) 텍스트파일과이진파일 텍스트파일 ( 텍스트모드 ) 로읽은경우 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 도단순한데이터로취급하여그대로읽혀진다. 7
파일과파일입출력 (3/9) 시스템콜 (System Call) open() user application user mode kernel mode system call interface i open() system call 의구현... return 8
FILE 구조체 파일과파일입출력 (4/9) 파일또는텍스트스트림에관한정보를저장하는구조체 파일이름, 파일버퍼의위치, 파일의현재상태등의정보를가지고있다. 입출력처리를위해포함 : <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 9
파일과파일입출력 (5/9) 파일열기 : 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); } 10
파일과파일입출력 (6/9) 파일열기 (cont d) fopen 함수의파일열기모드 : 텍스트모드 (text mode) 모드의미비고 r w a r+ 읽기전용 (Read Only) 파일이없으면 NULL을반환쓰기전용 (Write Only) 파일이존재하지않으면새파일을생성기존파일이있으면그내용은무시하고처음부터새로쓴다. 추가모드 (Append Only) 파일이존재하지않으면새파일을생성기존파일이있으면기존파일의끝에추가만가능하다. 기존파일에대한읽기와쓰기가모두가능하도록파일개방파일이없으면 NULL을반환 쓰기불가읽기불가읽기불가읽기 + 쓰기 w+ 무조건새로운파일을생성하여읽기와쓰기가가능하도록파일을연다. 읽기 + 쓰기 a+ 기존파일의끝에서부터읽기와쓰기가가능하도록파일을열고, 파일이없으면새로생성한다. 이전부분은쓰기불가 11
파일과파일입출력 (7/9) 파일열기 (cont d) fopen 함수의파일열기모드 : 이진모드 (binary mode) 모드 의미 rb, wb, ab 이진모드로파일을개방하고텍스트모드에서의 r, w, a와같은의미 r+b, rb+ w+b, wb+ 이진모드로파일을개방하고텍스트모드에서의 r+, w+, a+ 와동일한의미 a+b, ab+ 12
파일닫기 : fclose 파일과파일입출력 (8/9) 파일을더이상사용할필요가없을경우에는파일을닫아서버퍼공간과같은시스템자원을반납하여야한다. int fclose(file *stream); #include <stdio.h> 호출성공 : 0 을반환호출실패 : EOF 를반환 int main(void) FILE *fp;... fp = fopen( test.txt, w );... } fclose(fp); 13
파일과파일입출력 (9/9) 전형적인파일처리작업형태 #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); fclose(fpout); } return 0; 14
텍스트파일입출력함수 파일입출력 텍스트파일입출력함수 문자입출력함수 : fgetc, fputc 문자열입출력함수 : fgets, fputs 서식화된파일입출력함수 : fscanf, fprintf 이진파일입출력함수 다양한파일처리함수 15
텍스트파일입출력함수 (1/8) 문자입출력함수 : 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 를반환 16
텍스트파일입출력함수 (2/8) 문자입출력함수 : ungetc 지정된문자를입력스트림에되돌려놓는다 (getc 함수와반대동작 ). 이스트림을다음에읽으면지금되돌려진문자가반환될것이다. #include <stdio.h> int ungetc (int ch, FILE *stream); ch = getc(stdin); if (isdigit(ch)) ungetc(option, stdin); else... } 17
텍스트파일입출력함수 (3/8) 프로그램예제 : 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; 18
텍스트파일입출력함수 (4/8) 프로그램예제 : 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; 19
텍스트파일입출력함수 (5/8) 문자열입출력함수 : 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 를반환 20
텍스트파일입출력함수 (6/8) 프로그램예제 : fgets 와 fputs 을이용한타자기프로그램 #include <stdio.h> #include <stdlib.h> int main(void) char FILE str[1024]; *fpout; if (!(fpout = fopen ( data.txt", "w"))) printf( data.txt 파일개방실패!!! \n"); exit (100); } 파일에출력 while ( fgets (str, sizeof (str), stdin) ) fputs (str, fpout); fclose (fpout); } return 0; 21
텍스트파일입출력함수 (7/8) 서식화된파일입출력함수 : fscanf, fprintf 파일을대상으로서식화된입력기능을지원하는함수 #include <stdio.h> int fscanf(file *stream, const char *format, 가변길이인수리스트 ); 반환 ( 성공 ) : 정수를반환 ( 실패 ) : EOF 를반환 파일을대상으로서식화된출력기능을지원하는함수 #include <stdio.h> int fprintf(file *stream, const char *format, 가변길이인수리스트 ); 반환 ( 성공 ) : 정수를반환 ( 실패 ) : EOF 를반환 22
텍스트파일입출력함수 (8/8) 프로그램예제 : 텍스트파일에서학생성적을읽어들여출력 #include <stdio.h> #include <stdlib.h> int main(void) char int double ave; FILE *fpin; name[10]; kor, eng, math, tot; 파일내용읽기 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; 23
이진파일입출력함수 파일입출력 텍스트파일입출력함수 이진파일입출력함수 이진파일입출력함수 : fread, fwrite 다양한파일처리함수 24
이진파일입출력함수 (1/4) 이진파일입출력함수 : 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 : 대상이되는파일포인터 25
이진파일입출력함수 (2/4) 프로그램예제 : 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"; 26
이진파일입출력함수 (3/4) 프로그램예제 : fread 와 fwrite 를이용한블록입출력 (2/3) int main(void) int FILE SCORE count; *fp; temp; fp = fopen(file, "wb"); if(fp == NULL) printf(" 파일개방실패!!! \n"); exit(100); } printf(" 이름 : "); printf(" 국어 : "); printf(" 영어 : "); printf(" 수학 : "); gets(temp.name); scanf("%d", &temp.kor); scanf("%d", &temp.eng); scanf("%d%*c", &temp.math); temp.tot = temp.kor + temp.eng + temp.math; temp.ave = (float)temp.tot / 3; fwrite(&temp, sizeof(score), 1, fp); fclose(fp); 27
이진파일입출력함수 (4/4) 프로그램예제 : 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; 28
다양한파일처리함수 파일입출력 텍스트파일입출력함수 이진파일입출력함수 다양한파일처리함수 랜덤액세스함수 : fseek, ftell 오류처리관련함수 기타함수 29
다양한파일처리함수 (1/6) 랜덤액세스함수 : 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 파일의마지막위치를기준으로파일포인터를이동하겠다는뜻 30
다양한파일처리함수 (2/6) 랜덤액세스함수 (cont d) ftell 함수 : 파일포인터의위치를얻어오는함수 첫시작위치부터현재 stream 위치까지의거리를 long 형으로알려준다. int ftell(file *stream); 반환 ( 성공 ) : 파일의시작부터현재파일포인터까지의거리 ( 실패 ) : -1 을반환 31
다양한파일처리함수 (3/6) 오류처리관련함수 feof 함수 : 파일의끝에도달했는지여부를알려주는함수 파일의끝을읽으면 0 이아닌수를반환하고, 그렇지않은경우는 0 을반환한다. int feof(file *stream); feof 함수의일반적인사용형식 while (!feof(fp)) // 파일의끝이아니라면 putchar(fgetc(fp)); // 한문자씩읽어서화면에바로출력 32
다양한파일처리함수 (4/6) 오류처리관련함수 (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); 33
다양한파일처리함수 (5/6) 오류처리관련함수 (cont d) perror 함수 : 입출력오류가발생할경우에오류메시지를콘솔로출력 파일이없거나이미존재하는경우등다수의상황에따른오류코드를 error.h 에매크로상수로정의해두는데, 오류가발생할경우 errno 에자동으로저장된다. void perror(const char *errmsg); #include <errno.h> fp = fopen( perror.txt, r ); if (!fp) perror( Unable to open file for reading ); printf( errno = %d\n, errno ); } 34
다양한파일처리함수 (6/6) 기타함수 : fflush fflush 함수 : 대상이되는파일버퍼를비우는함수 int fflush(file *stream); Stream이 stdout인경우는입출력버퍼를비우고, stream가디스크파일스트림인경우는파일버퍼를비움으로써버퍼의내용을최종적으로디스크에기록한다. 작업이성공적일때는 0 을반환하고, 실패한다면 EOF 를반환 만약 stream 이 NULL 인경우라면모든디스크버퍼를비운다. 35
참고문헌 [1] 서두옥, 이동호 ( 감수 ), ( 열혈강의 ) 또하나의 C : 프로그래밍은셀프입니다, 프리렉, 2012. [2] Paul Deitel, Harvey Deitel, "C How to Program", Global Edition, 8/E, Pearson, 2016. [3] SAMUEL P. HARBISON Ⅲ, GUY L. STEELE, C 프로그래밍언어, C : A Reference Manual, 5/E, Pearson Education Korea, 2005. [4] 문병로, 쉽게배우는알고리즘 - 관계중심의사고법, 개정판, 한빛아카데미, 2018. [5] 주우석, CㆍC++ 로배우는자료구조론, 한빛아카데미, 2015. [6] Behrouz A. Forouzan, Richard F. Gilberg, 김진외 7인공역, 구조적프로그래밍기법을위한 C, 도서출판인터비젼, 2004. [7] Brian W. Kernighan, Dennis M. Ritchie, 김석환외 2인공역, The C Programming Language, 2/E, 대영사, 2004. [8] 김일광, C 프로그래밍입문 : 프로그래밍을모국어처럼유창하게, 한빛미디어, 2004. [9] 정재은, " 다시체계적으로배우는 C 언어포인터 ", 정보문화사, 2003. 이강의자료는저작권법에따라보호받는저작물이므로무단전제와무단복제를금지하며, 내용의전부또는일부를이용하려면반드시저작권자의서면동의를받아야합니다. Copyright Clickseo.com. All rights reserved. 36