Chapter 13 Input/Output and Files 프로그래밍 기초와 실습 Chapter 13 Input/Output and Files
Contents File pointer Function feof() File Operation Function fopen(), fclose() Formatted I/O Function fprintf(), fscanf() Character I/O Function getc(), putc() Using Command Line Arguments Double-Spacing a File
Contents The I/O Function in stdio.h String I/O Function sprintf() String I/O Function sscanf() Line I/O Function fputs() Line I/O Function fgets() Using Temporary Files and Graceful Functions Accessing a File Randomly
File pointer File pointer 선언 ‘FILE’ Type File I/O는 disk file명이 아닌 file pointer를 통해 stream을 생성하여 수행. 선언 ‘FILE’ Type stdio.h file에서 typedef로 정의된 type으로 file에 대한 여러 정보를 수록한 struct type [Ex] FILE *fp; /* file pointer로 ‘fp’ 선언 */
feof() Function feof() feof() Syntax 현재의 file pointer가 file의 끝까지 다 읽었는지를 알아보는 함수 feof() Syntax int feof( FILE *stream ); Returns 0 : EOF일 경우 none-zero : EOF가 아닐경우 open했던 file pointer name
File Operation Function fopen() fopen() Syntax FILE *fopen( const char *filename, const char *mode ); file pointer로 return disk에 있는 filename file open시의 mode [Ex] fp = fopen( “in.txt”, “r”); /* 읽기 전용으로 in.txt파일을 연다. */
File Operation Function fopen() Mode Strings for Text/Binary Files String Meaning “r” “w” “a” “rb” “wb” “ab” “r+” “w+” “a+” “rb+” “wb+” “ab+” open text file for reading open text file for writing open text file for appending open binary file for reading open binary file for writing open binary file for appending open text file for reading and writing, starting at beginning open text file for reading and writing(truncate if file exists) open text file for reading and writing (append if file exists) open binary file for reading and writing, starting at beginning open binary file for reading and writing(truncate if file exists) open binary file for reading and writing (append if file exists)
File Operation Function fopen() [Ex] #include <stdio.h> int main(void) { int sum = 0; val; FILE *ifp, *ofp; ifp = fopen(“my_file”, “r”); /* open for reading */ ofp = fopen(“outfile”, ”w”); /* open for writing */ … if ( ifp == NULL || ofp == NULL ) printf(“ Can’t open file”); } … ifp, ofp가 NULL pointer가 되는 경우 에러 메세지 출력
File Operation Function fclose() fopen으로 open한 파일의 사용이 끝나면 fclose를 써서 파일을 닫을 때 필요한 명령어 fclose() Syntax int fclose( FILE *stream ); Returns 0 : successful EOF : error (EOF is defined as –1 in stdio.h) open했던 file pointer name
File Operation Function fclose() [Ex] #include <stdio.h> #include <stdlib.h> #define FILE_NAME “example.dat” main() { FILE *fp; fp = fopen(FILE_NAME, “r”); if ( fp == NULL ) { printf(“Can’t open %s\n”, FILE_NAME); exit(EXIT_FAILURE); } … fclose(fp); return 0; } example.dat란 파일을 FILE_NAME로 define해서 사용하는 것은 좋은 프로그래밍 습관이다. reading가능하게 file pointer의 file을 open한다.
Formatted I/O Function fprintf() 출력결과를 FILE *fp의 파일로 보낸다. stdio.h 파일에 있는 fprintf()의 prototype fprintf() Syntax int fprintf( FILE *fp, const char *format, … ); fprintf( file_ptr, control_string, other_arguments );
Formatted I/O Function fscanf() keyboard로 입력을 받지 않고, 첫 번째 argument가 포인트하는 곳으로부터 입력 받는다. 실행에 성공하면 변환된 항목의 개수를 return한다. stdio.h 파일에 있는 fscanf()의 prototype fscanf() Syntax int fscanf( FILE *fp, const char *format, … ); fscanf( file_ptr, control_string, other_arguments );
Formatted I/O Function fprintf() and fscanf() stdio.h에 있는 3가지 file pointer Standard C files in stdio.h Written in C Name Remark stdin standard input file connected to the keyboard stdout standard output file connected to the screen stderr standard error file [Ex] fprintf(stdout, … ); is equivalent to printf(…); fscanf(stdin, … ); is equivalent to scanf(…);
Formatted I/O Function fprintf() and fscanf() fprintf(), fscanf() 예제 [Ex] #include <stdio.h> #include <stdlib.h> #define FILE_NAME "data.txt" main() { FILE *fp; char s; fp = fopen(FILE_NAME, "w+"); fprintf(fp, "C Programming is Hard"); fclose(fp); /* continue */ FILE_NAME을 읽고 쓰기 가능한 상태로 open해서 fp로 point한다. data.txt 파일에 문장을 저장한 후에 fclose로 file을 닫는다.
Formatted I/O Function fprintf() and fscanf() fprintf(), fscanf() 예제 fp = fopen(FILE_NAME, "r"); fscanf(fp, "%c", &s); printf("%c\n", s); fclose(fp); return 0; } FILE_NAME을 읽기만 가능한 상태로 open해서 fp로 point한다. fp가 point하는 file의 첫 번째 문자를 읽고 s에 저장한다. 위에서 읽은 s값을 출력한다. C
Character I/O Function getc() 외부 file로 부터 문자를 읽는 함수 getc는 보통 macro로 구현되어있고 stream의 실행은 최소한 한번 이상이다. fgetc( )와 동일 getc() Syntax int getc ( FILE *stream ); stream이 point하고 있는 파일 이름 [Ex] while ( ( c = getc( ifp ) ) != EOF ) ifp가 포인트 하는 파일로부터 문자를 읽어 들여 그 값을 c에 저장한다.
Character I/O Function putc() 외부 file에 문자를 저장하는 함수. fputc()와 동일 putc() Syntax int putc ( int c, FILE *stream ) ; putc가 에러없이 끝나면 c와 동일한 값을 리턴 c를 unsigned char로 변환하고, *stream이 저정하는 파일에 이것을 쓴다. [Ex] putc( c, ofp ); ofp가 포인트하는 파일에 c 값을 쓴다.
Using Command Line Arguments C program은 command line에서 argument를 program으로 access 가능하게 한다. Syntax ( Example in Unix System ) 사용예 [prompt ] program_name arg1 arg2 … argN 실행 가능한 file name [Ex] a.out file1.txt file2.txt a.out이라는 실행파일을 실행할 때 두개의 인자로서 file1.txt와 file2.txt를 사용
Using Command Line Arguments argc ( argument count ) 명령어 라인의 인자 개수를 포함하는 정수 프로그램 실행 시, 적어도 하나의 실행파일을 포함하기 때문에 항상 1 이상의 값을 가진다. [Ex] main(int argc, char *argv[]) { … }
Using Command Line Arguments argv ( argument vector ) 문자열의 배열로 생각할 수 있는 char형 포인터 배열 argv[0]은 명령어 자체의 이름을 포함한다. 사용예 argv[0] program_name argv[1] pointer to the 1st argument : : argv[n] pointer to the nth argument [Ex] [prompt] a.out Hello Handong argv[0] argv[1] argv[2]
Using Command Line Arguments [Ex] main (int argc, char * argv[]){ int count; printf( “%s\n”, argv[0] ); /* Retrieve the program_name */ if( argc > 1 ){ for( count = 1 ; count < argc ; count++ ) printf(“%d %s\n”, count, argv[count] ); else puts( “No comand line arguments” ); } argument가 있다면 그 argument 모두를 출력하기 만일 argc가 1이라면, 즉 program명으로만 command line이 구성되었다면 no command line arguments를 출력하는 code
Using Command Line Arguments atoi() prototype은 stdlib.h에 있다. 문자열 pt를 int로 변환하고 그것을 리턴한다. 변환이 일어나지 않으면 0을 리턴한다. atof() 문자열 pt를 double로 변환하고 그것을 리턴한다. int atoi(const char * pt); double atof(const char * pt); /* Convert a string to a double */
Using Command Line Arguments +, -, x, *의 calculator program [Ex] main (int argc, char * argv[]){ int i,s; switch( * argv[i] ){ case ‘+’ : s=0; for( i = 2; i < argc ; i++) s = s + atoi(argv[i]); break; case ‘-’ : s = atoi( argv[2] ) – atoi( argv[3] ); break; case ‘*’ : for( i = 2 ; i < argc ; i++ ) s = s * atoi( argv[i] ); break; case ‘/’ : s = atoi( argv[2] ) / atoi( argv[3] ); break; } printf(“%d\n”, s); command line의 두 번째 argumen를 check 각각의 operator에 따라서 계산
Using Command Line Arguments +, -, x, *의 calculator program /* 유닉스 시스템에서 실행 */ [prompt] cc cal.c –o calc /* source program의 Compile */ [prompt] calc + 2 4 6 8 /*이와 같이 실행 file의 수행 시 결과 : 20 */ [prompt] calc * 7 8 1 1 /*이와 같이 실행 file의 수행 시 결과 : 56 */
Double-Spacing a File [Ex] #include <stdio.h> #include <stdlib.h> void double_space( FILE *, FILE * ); void prn_info( char * ); int main ( int argc, char **argv ) { FILE *ifp, *ofp; if( argc != 3 ) { prn_info(argv[0]); exit(1); } ifp = fopen( argv[1], “r” ); /* open for reading */ ofp = fopen( argv[2], “w” ); /* open for writing */ fclose(ifp); fclose (ofp); return 0; } prn_info()함수에서 exit()함수를 사용하기 때문에 포함시킴 명령어 라인의 인자로 두 개의 파일에 접근하게 되어있다. ex) a.out file1 file2 ifp, ofp는 파일 포인터 exit()함수는 오류가 발생하면 0이 아닌 값을 리턴한다.
Double-Spacing a File void double_space( FILE *ifp, FILE *ofp ) { int c; while ( ( c = getc(ifp) ) != EOF ) { putc(c, ofp); if ( c == ‘\n’ ) putc(‘\n’ ofp ); /* found newline – duplicate it */ } void prn_info( char *pgm_name ) printf(“\n%s%s%s\n\n%s%s\n\n”, “Usage: “, pgm_name, “infile outfile”, “The contents of infile will be double-spaced “, “and written to outfile.” ); 실행파일이 dbl_sapce라면, dbl_space file1 file2 로 실행한다.
The I/O Function in stdio.h standard I/O로 출력은 모니터 fp가 지정하는 파일에 문자를 쓰고 씌어진 문자의 개수를 리턴 한다. 출력 결과를 화면에 출력하는 대신 s가 포인트하는 문자열에 쓴다. printf(“%d”, a); int fprintf(FILE fp, const char *control_string, …); int sprintf(char *s, const char *control_string, …);
The I/O Function in stdio.h standard I/O로 입력은 키보드로 한다. fp가 지정하는 파일로부터 control_string의 지시에 따라 문자를 읽는다. 키보드로 입력을 받는 대신 s가 포인트하는 문자열로부터 읽는다. scanf와의 차이점은 sscanf를 이용하여 읽을 경우 이전에 s로부터 읽고 남겨진 부분부터 읽는 것이 아니라 문자열의 시작점부터 다시 읽는다. scanf(“%d”, &a); int fscanf(FILE fp, const char *control_string, …); int sscanf(char *s, const char *control_string, …);
String I/O Function sprintf() 문자열 (string) 처리를 위한 printf()문이다. 결과를 화면에 출력하는 대신에, 첫 번째 argument인 char형 포인터가 포인트하는 곳에 출력한다. stdio.h 파일에 있는 sprintf()의 prototype sprintf() Syntax int sprintf( char *s, const char *format, … ); sprintf( string, control_string, other_arguments );
String I/O Function sscanf() 문자열 (String) 처리를 위한 scanf()문이다. keyboard로 입력을 받지 않고, 첫 번째 argument가 포인트하는 곳으로부터 입력 받는다. stdio.h 파일에 있는 sscanf()의 prototype sscanf() Syntax int sscanf( const char *s, const char *format, … ); sscanf( string, control_string, other_arguments );
String I/O Function sprintf() and sscanf() [Ex] char in_string[] = “1 2 3 go”; char out_string[100], tmp[100]; int a, b, c; sscanf( in_string, “%d%d%d%s”, &a, &b, &c, tmp ); sprintf(out_string, “%s %s %d%d%d\n”, tmp, tmp, a,b,c); printf(“%d”, out_string); go go 123
String I/O Function sprintf() and sscanf() FILE I/O 를 포함한 예제 [Ex] #include <stdio.h> main() { char c, s[] = “abc”, *p = s; int i; FILE *ofp1, *ofp2; ofp1 = fopen(“tmp1.txt”,”w”); ofp2 = fopen(“tmp2.txt”,”w”); for( i = 0 ; i < 3 ; ++i ) { sscanf(s, “%c”, &c); fprintf( ofp1, “%c”, c ); } fprintf( ofp2, “%c”, c ); fclose(ofp1); fclose(ofp2); ofp2가 point하고 있는 파일에 문자를 write tmp1.txt = abc tmp2.txt = c₩337₩276 ofp1이 point하고 있는 파일에 문자를 write
Line I/O Function fputs() fputs() : Writing a string fp가 지정하는 파일에 NULL로 끝나는 문자열 str을 복사한다. NULL 부분 전까지 파일로 복사된다. 호출이 성공하면 음수가 아닌 값을 리턴한다. 호출이 실패하면 EOF를 리턴한다. fputs() Syntax int fputs(char *str, FILE *fp);
Line I/O Function fputs() [Ex] FILE *fp; char filen[] = "test"; int i; char *data[]={"to be\n","or not\n","to be\n"}; fp = fopen(filen, "w"); for(i = 0; i<3; i++) fputs(data[i],fp); fclose(); 각 string끝에 ‘\n’이 없는 경우 fputs( strcar( data[i],"\n”),fp);
Line I/O Function fgets() fgets() : Reading a String fp가 지정하는 파일에서 최대 num – 1개의 문자를 읽어 str이 포인트하는 배열에 저장한다. ‘\n’이나 EOF를 만나면 읽기를 중단하고 NULL을 저장한다. 읽기가 성공하면 str을 리턴하고 그렇지 않으면 NULL을 리턴한다. fgets() Syntax char *fgets(char *str, int num, FILE *fp);
Line I/O Function fgets() gets함수와 fgets함수의 차이 gets함수 : new line의 저장 안됨 ( new line은 자동 '\0'으로 convert됨 ) fgets함수 : new line 의 read시 저장 됨 ( 끝에 '\0'자동 추가 ) [Ex] fgets(str, num, stdin); KB통해 string의 read
Line I/O Function fputs() [Ex] /* file ‘testin’ -> file ‘test.out’ 으로 copy */ FILE *ip, *op; char line[80],c; ip = fopen("testin", "r"); op = fopen("testout","w"); while( fgets(line, 80, ip) != NULL) fputs(line,op); fclose(ip); fclose(op); ip가 지정하는 파일에서 80개까지의 문자를 읽어 line에 저장한다.
Using Temporary Files and Graceful Functions tmpfile() C에서 파일이 닫히거나 프로그램이 종료될 때 자동적으로 삭제되는 임시 파일을 생성하기 위한 함수 최신의 자료로 수정되기 위해 “wb+” 모드로 열림 tmpfile Syntax FILE *tmpfile(void); char *tmpnam(char *s); [Ex] FILE *tempptr; tempptr = tmpfile( ); /* creates a temporary file */
Using Temporary Files and Graceful Functions [Ex] /* 외부 파일의 내용을 소문자에서 대문자로 바꾸어 주는 프로그램 */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> FILE *gfopen( char *filename, char *mode ); int main(int argc, char **argv) { int c; FILE *fp, *tmp_fp; if (argc != 2 ) { fprintf(stderr, “\n%s%s%s\n\n%s%s\n\n”,“Usage: “, argv[0], “ filename”, “The file will be doubled and som letters capitalized.“); exit(1); } /* continue… */ *gfopen함수의 prototype 명령어 라인의 argument가 2개가 아니면 에러 메세지를 출력한다.
Using Temporary Files and Graceful Functions fp = gfopen(argv[1], “r+”); tmp_fp = tmpfile(); while ( ( c = getc(fp) ) != EOF ) putc(toupper(c) , tmp_fp ); fprintf(fp, “---\n”); rewind(tmp_fp); while ( ( c = getc(tmp_fp) ) != EOF ) putc( c, fp ); return 0; } FILE *gfopen(char *fn, char *mode) { FILE *fp; if( ( fp = fopen(fn, mode ) ) == NULL ) { fprintf(stderr, “Cannot open %s – bye!\n”, fn ); exit(1); } return fp; } 외부 파일을 r+ mode를 써서 open한다. 외부 파일의 내용을 character 단위로 입력받아 EOF가 될 때까지 toupper() 함수를 사용하여 대문자로 변환한다 file pointer의 indicator를 file의 시작하는 부분으로 옮긴다. tmp_fp에 저장되어있던 문자들을 출력하는 부분 외부 파일 이름과 open mode 를 argument로 입력받아 function 실행 C Programming ---------------------- C PROGRAMMING
Accessing a File Randomly fseek(), ftell()은 파일에 random하게 접근하는데 사용 file position indicator의 현재 값을 return한다. return된 값은 처음을 0으로 두고 처음부터 몇 byte 떨어져 있는가의 값을 나타낸다. 파일로부터 한 문자씩 읽을 때 마다 indicator의 값을 1증가 시킨다. place에서 offset만큼 떨어진 위치에 file position indicator를 둔다. place의 값은 0 (파일의 맨처음 ), 1 (현재위치), 2(맨끝)의 값을 갖는다. ftell(file_ptr); fseek( file_ptr, offset, place);
Accessing a File Randomly [Ex] #include <stdio.h> #define MAXSTRING 100 int main(void) { char file_name[MAXSTRING]; int c; FILE *ifp; fprintf(stderr, “\nInput a file name: “); scanf(“%s”, file_name ); ifp = fopen(file_name, “r” ); fseek(ifp, 0, 2); fseek(ifp, -1, 1); /* continue */ file_name이 가리키는 파일 안에 C Programming 이라는 문장이 있다고 가정하여 설명. 문장의맨 끝에서 0번째 위치에 ifp를 둔다. ( 13번째 위치 ) 문장의 현재위치(위의 결과로 끝 문자) 에서 -1번째, 즉 앞 문자에 ifp를 둔다. ( 12번째 위치 )
Accessing a File Randomly while ( ftell(ifp) > 0) { c = getc(ifp); putchar(c); fseek(ifp, -2, 1); } return 0; ifp가 0보다 클 동안 while 함수를 실행하는데 true일 경우 ifp의 indicator 값을 하나 증가시킨다. ( 13번째 위치 ) ifp가 point 하고 있는 문자를 출력 fseek함수를 이용하여 현재위치에서 앞에 두 번째 문자를 ifp로 한다. ( 11번째 위치 ) gnimmargarP^
Input / Output and Files 수고하셨습니다 Input / Output and Files