제 5 장 C 표준라이브러리 숙대창병모 1
목표 C 표준라이브러리의깊이있는이해 시스템호출과 C 표준라이브러리관계 숙대창병모 2
C 입출력라이브러리함수 숙대창병모 3
시스템호출과라이브러리함수 System Calls well defined entry points directly into the kernel documented in section 2 of the UNIX man pages look like C functions which can be called from a user's program just need to include the appropriate header C Library Functions the library function is often more elaborate than the system call, and usually invokes the system call 숙대창병모 4
시스템호출과라이브러리함수 C library functions application code user process system calls kernel kernel hardware (harddisk ) 숙대창병모 5
CSt Standard di/olib Library Written by Dennis Ritchie in 1975 Implemented on many OS ANSI C Standard Library Buffer allocation 최적의크기단위로 I/O 를수행 디스크 I/O 횟수최소화 Streams 문자의흐름으로파일입출력을다룬다 숙대창병모 6
파일열기 파일입출력과정 파일열기, 읽기 / 쓰기, 파일닫기 파일열기 fopen() #include <stdio.h> FILE *fp; fp=fopen(" 파일이름 ", " 입출력방식 "); 숙대창병모 7
fopen 모드 모드 "r" "w"" 읽기전용으로연다 내용 쓰기전용으로연다. 파일이없으면새로생성하고이미존재하면그파일내용을삭제 "a" 추가용으로연다. 파일이없으면새로생성한다. "r+" r+ 이미존재하는파일을읽기쓰기 ( 갱신 ) 용으로연다. "w+" 파일을생성하고갱신용으로연다. "a+" 파일을추가용, 갱신용으로연다. 파일이없으면새로생성한다. "rb" 이진파일을읽기용으로연다. "wb" 이진파일을쓰기용으로연다. "ab" 이진파일을추가용으로연다. 파일이없으면새로생성한다. "rb+" 이미존재하는이진파일을갱신용으로연다. "wb+" 이진파일을생성하고갱신용으로연다. "ab+" 이진파일을추가용, 갱신용으로연다. 파일이없으면새로생성한다. 숙대창병모 8
FILE 구조체 파일관련시스템호출함수 파일디스크립터 (file descriptor) 표준입출력함수 FILE 구조체에대한포인터 하나의스트림을다루기위한정보를포함하는구조체 버퍼에대한포인터, 버퍼크기 에러플래그등 파일디스크립터 (File descriptor) #include <stdio.h> 숙대창병모 9
FILE 구조체 열린파일의상태를저장하기위한구조체 <stdio.h> 에정의되어있음 typedef struct { int _cnt; // 버퍼에남아있는문자의수 unsigned char *_ptr; // 버퍼내에다음쓸 ( 읽을 ) 위치포인터 unsigned char *_base; // 버퍼시작주소 unsigned char _flag; // 스트림의현재상태 _IOFBF, _IOLBF, _IONBUF _IOEOF, _IOERR _IOREAD, _IOWRT unsigned char _file; // 파일디스크립터 } FILE ; 숙대창병모 10
FILE 구조체 FILE * (FILE 구조체에대한포인터 ) 스트림을열면 (fopen 함수 ) 리턴됨 열린파일을가리키는 FILE 포인터 표준 I/O 함수들의매개변수로전달해야함 프로그래머는 FILE 구조체의내부를알필요없음 숙대창병모 11
표준입력 / 출력 / 에러 표준 I/O 스트림 (stream) 프로그램이시작되면자동으로 open 되는스트림 stdin, stdout, stderr FILE* #include <stdio.h> 표준입출력포인터 설명 가리키는장치 stdin 표준입력에대한 FILE 포인터키보드 stdout t 표준출력에대한 FILE 포인터모니터 stderr 표준오류에대한 FILE 포인터모니터 숙대창병모 12
표준입출력 : 예 숙대창병모 13
fclose() #include <stdio.h> int fclose ( FILE *fp ); 스트림을닫는다 리턴값 : 성공하면 0, 실패하면 EOF (-1) 출력버퍼에있는모든자료는파일에저장되고, 입력버퍼에있는모든자료는버려진다. 프로세스가정상적으로종료한경우에는모든열려진스트림이저절로닫힌다 숙대창병모 14
표준 / 파일입출력함수 표준입출력함수 표준파일입출력함수 기능 getchar() fgetc(), getc() 문자단위로입력하는함수 putchar() fputc(), putc() 문자단위로출력하는함수 gets() fgets() 문자열을입력하는함수 puts() fputs() 문자열을출력하는함수 scanf() fscanf() f() 자료형에따라자료를입력하는함수 printf() fprintf() 자료형에따라자료를출력하는함수 숙대창병모 15
파일입출력함수 파일입력함수 fscanf(), fgets(), fgetc() 열린파일에서내용을읽어들이는함수 파일출력함수 fprintf(), fputs(), fputc() 열린파일에내용을기록하는함수 파일닫기 fclose() 숙대창병모 16
파일입출력 : 예 숙대창병모 17
파일복사 1: 예 숙대창병모 18
파일복사 2: 예 #include <stdio.h> int main(argc, argv) int argc; char* argv[]; { FILE *fp1, *fp2; char buffer[100];// 데이터를임시로저장하기위한배열 fp1 =fopen(argv[1], r"); fp2 =fopen(argv[2], "w");") if(fp1==null) printf("file not found"); /* 최대길이가 100 인문자열을 fp 가가리키는파일에서읽어서 buffer 에저장후 fp_write 가가리키는파일에 buffer 내용기록 */ while(fgets(buffer, 100, fp1)!=null) fputs(buffer, fp2); } fclose(fp1); fclose(fp2); 숙대창병모 19
파일위치 (file position) i fseek(file *fp, long offset, int mode) FILE 포인터 fp가가리키고파일의파일위치를모드 (mode) 가나타내는기준점을기준으로오프셋 (offset) 만큼옮긴다. rewind(file *fp) 파일위치를파일시작점에위치시킴으로써처음부터다시읽을수있게한다. ftell(file *fp) FILE 포인터 fp가가리키고있는파일의현재파일위치를나타내는파일위치지정자값을반환한다. 숙대창병모 20
fseek(, int mode) 숙대창병모 21
블록단위입출력 int fread( void *buf, int size, int n, FILE *fp ); fp 가가리키는파일에서 size 크기의블록을 n 개읽어서버퍼포인터 buf 가가리키는곳에저장한다. 읽은블록의수를반환한다. int fwrite( const void *buf, int size, int n, FILE *fp ); 파일포인터 fp가지정한파일에버퍼 buf에저장되어있는 size 크기의블록 ( 연속된바이트 ) 을 n 개기록한다. 숙대창병모 22
블록출력 : 예 struct student st; FILE *fp = fopen("st_file", "w");... /* 입력된학생정보를 st 에저장 */ fwrite(&st, sizeof(struct student), 1, fp) st 숙대창병모 23
블록수정 : 예 fread(&st, sizeof(struct student), 1, fp); // 학생정보수정 fseek(fp, -sizeof(struct student), SEEK_CUR); fwrite(&st, sizeof(struct student), 1, fp); 숙대창병모 24
파일복사 3: 예 #include <stdio.h> #define MAXSIZE 256 int main(argc, argv) int argc; char *argv[]; { FILE *fpin, *fpout; char buffer[maxsize]; int num; } fpin = fopen(argv[1], "r"); fpout = fopen(argv[2], "w"); if(fpin == NULL fpout == NULL) { fprintf(stderr, " 파일열기오류 \n"); exit(1); } while((num = fread(buffer, 1, MAXSIZE, fpin)) > 0) { fwrite(buffer, num, 1, fpout); } fclose(fpin); fclose(fpout); printf(" 파일복사완료 \n"); 숙대창병모 25
C library buffer 숙대창병모 26
C library buffer Clb library buffer 사용목적 디스크 I/O 수행의최소화 read (), write () 함수호출의최소화 최적의크기단위로 I/O 수행 시스템성능향상 C library buffer 방식 fully buffered line buffered unbuffered 숙대창병모 27
C library buffer 방식 Fully Buffered 버퍼가꽉찼을때실제 I/O 수행 디스크파일입출력 Line Buffered 줄바꿈문자 (newline) 에서실제 I/O 수행 터미널입출력 (stdin, stdout) Unbuffered 버퍼를사용하지않는다. 표준에러 (stderr) 숙대창병모 28
setbuf()/setvbuf() t b #include <stdio.h> void setbuf (FILE *fp, char *buf ); int setvbuf (FILE *fp, char *buf, int mode, size_t size ); 버퍼의관리방법을변경한다 호출시기 스트림이오픈된후, 입출력연산수행전에호출되어야함 숙대창병모 29
setbuf() void setbuf (FILE *fp, char *buf ); 버퍼사용을 on/off 할수있다. buf 가 NULL 이면 unbuffered buf 가 BUFSIZ 크기의공간을가리키면 fully/line buffered 터미널장치면 line buffered 그렇지않으면 fully buffered 숙대창병모 30
setvbuf() int setvbuf (FILE *fp, char *buf, int mode, size_t size ); 버퍼사용방법을변경 리턴값 : 성공하면 0, 실패하면 nonzero mode _IOFBF : fully buffered _IOLBF : line buffered _IONBF : unbuffered 숙대창병모 31
setvbuf() mode == _IONBF buf 와 size 는무시됨 mode == _IOLBF or _IOFBF buf 가 NULL 이아니면 buf 에서 size 만큼의공간사용 NULL 이면라이브러리가알아서적당한크기할당사용 stat 구조체의 st_blksize 크기할당 (disk files) st_blksize 값을알수없으면 BUFSIZ 크기할당 (pipes) 숙대창병모 32
예제 :setbuf #include <stdio.h> /* buffer.c */ main() { printf("hello, "); sleep(1); printf("unix!"); sleep(1); printf("\n"); sleep(1); setbuf(stdout, NULL); printf("how "); sleep(1); printf("are "); sleep(1); printf("you?"); sleep(1); printf("\n"); sleep(1); } 숙대창병모 33
예제 : Pi Print buffering int main( ) { FILE *fp; fputs( enter any character\n, stdout); if (getchar() == EOF) perror( getchar error ); fputs( one line to standard error\n, stderr); } pr_stdio( stdin, stdin); pr_stdio( stdout, stdout); pr_stdio( stdio( stderr stderr, stderr); if ( ( fp = fopen( /etc/motd, r )) == NULL) perror( fopen error ); if (getc(fp) (f == EOF) perror( getc error ); pr_stdio( /etc/motd, fp); exit(0); 숙대창병모 34
예제 : Pi Print buffering #include <stdio.h> void pr_stdio(const char *name, FILE *fp) { print( stream = %s, name); if (fp->_flag & _IONBF) printf( unbuffered\n ); else if (fp->_flag & _IOLBF) printf( line buffered\n ); else printf( fully buffered\n ); printf(, buffer size =%d\n, fp->_bufsize); } 숙대창병모 35
fflush() #include <stdio.h> int fflush (FILE *fp); fp 스트림의출력버퍼에남아있는내용을 write() 시스템호출을통하여커널에전달한다 리턴값 : 성공하면 0, 실패하면 EOF (-1) fp 가 NULL이면, 모든출력스트림의출력버퍼에남아있는내용을커널에전달한다 숙대창병모 36