540 likes | 687 Views
Chapter 17 파일 처리. 함수 fopen(). 파일을 만들기 위해서는 함수 fopen() 을 이용 함수 fopen() 의 함수 원형은 다음과 같으며 헤더 파일 stdio.h 파일에 정의 함수 fopen() 에서 f 는 파일 (file) 의 f 를 의미 함수 fopen() 은 두 개의 문자열 전달인자를 이용 , 반환 값은 포인터 값인 FILE *
E N D
함수 fopen() • 파일을 만들기 위해서는 함수 fopen()을 이용 • 함수 fopen()의 함수 원형은 다음과 같으며 헤더 파일 stdio.h 파일에 정의 • 함수 fopen()에서 f는 파일(file)의 f를 의미 • 함수 fopen()은 두 개의 문자열 전달인자를 이용, 반환 값은 포인터 값인 FILE * • 반환 값의 유형인 FILE *에서 FILE은 헤더 파일 stdio.h 파일에 정의되어 있는 구조체 유형, 그러므로 반환 값의 유형 FILE *은 구조체 FILE의 포인터 유형 struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE;
파일 열기 • 함수fopen()에서첫번째문자열은처리하려는파일이름이고, 두번째문자열은파일처리종류(모드) • 다음소스는파일“basic.txt”을여는모듈로서, 파일에자료를쓰기위해파일을열므로모드값을“w”로기술 • 함수fopen()은성공적으로파일을열면(open), FILE 포인터를반환하므로그값을변수f에저장 • 함수fopen()은파일을여는데실패하면NULL 값을반환 • 조건문if를위와같이함수fopen()과함께이용하면파일열기에실패할경우문장"파일이열리지않습니다.\n"을출력 • 파일처리가모두끝났으면파일포인터f를인자로함수fclose(f)를호출하여반드시파일을닫도록 • 함수fopen()의두번째인자는파일처리종류(모드) • “r”, “w”, “a”, “r+”, “w+”, “a+”의종류 FILE *f; char fname[] = "basic.txt"; if ((f = fopen(fname, "w")) == NULL) { printf( "파일이열리지않습니다.\n" ); }; … fclose(f);
모드 의미 r 읽기(read) 모드로파일을연다. 파일이없으면에러가발생한다. w 쓰기(write) 모드로파일을연다. 파일이없으면새로만들고, 기존의파일이있으면그이전의내용은없어지고파일의처음부터쓴다. 이모드로는파일내용을읽을수없다. a 추가쓰기(append) 모드로파일을연다. 파일이없으면새로만들고, 기존의파일이있으면그파일의가장뒤부터파일에추가한다. r+ 읽기(read)와쓰기(write) 모드로파일을연다. 파일이없으면에러가발생한다. w+ 읽기와쓰기(write) 모드로파일을연다. 파일이없으면새로만들고, 기존의파일이있으면그이전의내용은없어지고파일의처음부터쓴다. a+ 추가쓰기(append) 모드로파일을연다. 파일이없으면새로만들고, 기존의파일이있으면그파일의가장뒤부터파일에추가한다. 파일의어느곳이나읽기는가능하나쓰기는추가적으로만가능하다. 파일 처리 모드 • 파일처리모드 종류의미
파일에 글자 쓰기 • 함수 fprintf() • 함수 fopen()을 이용하여 쓰기 모드로 파일을 연 다음, 원하는 자료를 파일에 써 보자. • C 언어는 파일에 자료를 쓰는 함수로 fprintf()를 제공 • 함수 fprintf()는 함수 printf()와 유사하며, 첫 인자로 출력하려는 목적지인 파일을 지정 • 위문장은파일f에문자열"이름이%s인학생의성적은%d 입니다.\n"을쓰는구문 • 위구문으로변수name과point에저장된문자열과정수값이적절히연결된문자열이파일에기록 fprintf(f, "이름이%s인학생의성적은%d 입니다.\n", name, point);
예제 소스 • Filebasic.c • 함수fopen(), fprintf()를이용하여표준입력으로받은이름과점수를파일“basic.txt”에출력하는프로그램 • 파일이쓰기모드로열리지않으면함수exit()를이용하여프로그램을종료 • 함수exit()를이용하려면헤더파일stdlib.h를포함 • 함수exit()는함수를강제로종료하는기능을수행하며, 인자로정수값을쓰는데, 0은정상적인종료를의미하고, 0이아닌값은정상적인종료가아님을운영체제에게알리는의미로사용 if ((f = fopen(fname, "w")) == NULL) { printf( "파일이열리지않습니다.\n" ); exit(1); };
표준파일 키워드 장치(device) 표준입력 stdin 키보드 표준출력 stdout 모니터화면 표준에러 stderr 모니터화면 함수 fprint, fscanf • 파일에자료를쓰거나읽기위하여함수fprintf()와fscanf()를이용 • 이함수를이용하기위해서는헤더파일stdio.h 파일을포함 • 함수fprintf()와fscanf()의함수원형 • 위함수의첫번째인자는입출력에이용될파일이고, 두번째인자는입출력되는문자열이며, 다음인자들은입출력될변수목록 • 함수원형에서기호…은여러인자가계속됨을의미 • 함수fprintf()와fscanf()를표준입출력에도이용 가능 • 즉함수fprintf()와fscanf()의첫번째인자에각각stdin 또는stdout를이용하면표준입력, 표준출력으로이용이가능 • 기호상수stdin, stdout은stderr과함께헤더파일stdio.h에정의되어있는값으로각각표준입력, 표준출력, 표준에러를의미 int fprintf(FILE *, const char *, ...); int fscanf(FILE *, const char *, ...); #define stdin (&_iob[0]) #define stdout (&_iob[1]) #define stderr (&_iob[2])
예제 소스 • 파일 내용 쓰기, 읽기를 처리하는 프로그램 • 쓰기 모드로 파일을 열어 • 표준입력으로 받은 이름과 중간 기말점수를 파일에 기록하고 파일을 닫은 후, • 다시 읽기 모드로 그 파일을 열어 기록된 내용을 파일에서 읽어와 표준출력으로 출력하는 프로그램 • 쓰기 모드로 파일을 열어 표준 입력으로 이름, 중간점수, 기말점수를 받는 모듈 • 표준입력의 이름을 빈칸으로 구분하므로 빈칸이 없는 이름을 입력해야 함 if ((f = fopen(fname, "w")) == NULL) { printf( "파일이열리지않습니다.\n" ); exit(1); }; printf("이름과성적(중간, 기말)을입력하세요.\n" ); scanf("%s%d%d", name, &point1, &point2);
구현 • 다음은 표준 입력으로 읽어들인 이름, 중간점수, 기말점수를 함수 fprintf()를 이용하여 파일 f에 출력하는 모듈 • 변수 cnt는 이름 앞에 번호를 붙이려는 목적으로 이용 • 다음은 위에서 자료를 쓴 파일의 내용을 다시 읽으려는 소스 • 파일을 읽기 모드로 열므로 모드 인자는 “r”로 지정 //파일"grade.txt"에쓰기 fprintf(f, "%d %s %d %d\n", ++cnt, name, point1, point2); fclose(f); if ((f = fopen(fname, "r")) == NULL) { printf( "파일이열리지않습니다.\n" ); exit(1); }; //파일"grade.txt"에서읽기 fscanf(f, "%d %s %d %d\n", &cnt, name, &point1, &point2);
구현 • 위에서 함수 fscanf()를 이용하여 파일에서 적당한 내용을 읽은 후, 다시 함수 fprintf()를 이용하여 표준출력으로 출력 • 파일에서 함수 fscanf()를 이용하려면 파일의 내부 자료의 저장 형태를 알아야 정확히 읽을 수 있음 • 출력은 먼저 머리 부분으로 제목을 출력하고 다음에 내용을 출력 • 함수fprintf()는첫인자를stdout으로지정하여표준출력으로이용 • 다음과같이함수printf()를이용도 가능 //표준출력에쓰기 fprintf(stdout, "\n%6s%18s%8s%8s\n", "번호", "이름", "중간", "기말"); fprintf(stdout, "%6d%18s%8d%8d\n", cnt, name, point1, point2); fclose(f); printf("%6d%18s%8d%8d\n", cnt, name, point1, point2);
예제 소스 • Filewrite.c • 파일 내용 쓰기, 읽기를 처리하는 프로그램 • 프로그램 실행이 성공적으로종료되면파일grade.txt 파일이생성
함수 fgets()와fputs() • 함수 fgets()와fputs() • 파일에 문자열을 입출력하는 함수로 fgets()와fputs() • 이함수도헤더파일stdio.h 파일에다음과같은함수원형으로정의 • 함수 fgets()는 문자열을 개행문자(\n)까지 읽어 개행문자도 함께 입력 문자열에 저장 • 마찬가지로함수 fputs()는 문자열을 그대로 출력 • 함수 fgets() 인자 • 첫 번째 인자는 문자열이 저장될 문자 포인터이고, • 두 번째 인자는 입력할 문자의 최대 수이며, • 세 번째 인자는 입력 문자열이 저장될 파일 • 함수 fputs() 인자 • 첫 번째 인자는 출력될 문자열이 저장된 문자 포인터이고, • 두 번째 인자는 문자열이 출력되는 파일 char * fgets(char *, int, FILE *); int fputs(char *, FILE *);
함수fgetc()와fputc() • 문자 하나를 파일에 입출력하는 함수로 fgetc()와 fputc()를 제공 • 이 함수의 원형은 헤더파일 stdio.h에 정의 • 이함수들은문자하나의입출력의대상인파일포인터를인자로이용 • 이함수와같은함수로getc()와putc()도이용가능 • 문자의표준입출력에이용되는getchar()와putchar()는다음과같이함수getc()와putc()를이용한매크로 • 함수fgetc()와 fputc()는 getc()와putc()와그기능은동일하며, fgetc()와 fputc()는 함수이고, getc()와putc()는매크로 int fgetc(FILE *); int fputc(int, FILE *); int getc(FILE *); int putc(int, FILE *); #define getchar() getc(stdin) #define putchar(_c) putc((_c),stdout)
함수feof()와ferror() • 함수feof() • 파일의내부포인터위치가파일의끝(EOF)인지를검사하는데필요한함수 • 이함수는헤더파일stdio.h에다음함수원형으로정의 • 파일의위치가파일의마지막(end of file)인지를검사하여, 파일의마지막이면0이아닌값을, 파일의마지막이아니면0을반환 • 그러므로표준입력에서계속적으로입력을받는구문으로다음을이용 가능 • 함수ferror() • 파일처리에서오류가발생했는지검사하는함수 • 함수의원형은헤더파일stdio.h에정의 • 이전파일처리에서오류가발생하면0이아닌값을발생하고, 오류가발생하지않으면0을반환 int feof(FILE *); while (!feof(stdin)) { … } int ferror(FILE *);
예제 소스 • 목적 • 함수 fgets()와 fputs()를이용하여표준입력으로여러줄을입력받아여러줄을지정된파일에출력하는 프로그램을 작성 • 구현 • 주요 변수 • 표준입력으로입력된한줄의자료를함수fgets()를이용하여입력 받고, 바로이한줄의문자열을함수fputs()를이용하여파일f에저장하는모듈 char fname[] = "grade.txt"; char names[80]; FILE *f; printf("이름과성적(중간, 기말)을입력하세요.\n" ); fgets(names, 80, stdin); while (!feof(stdin)) { //파일"grade.txt"에쓰기 fprintf(f, "%d ", ++cnt); fputs(names, f); fgets(names, 80, stdin); } fclose(f);
구현 • 파일의내용을파일의끝까지한줄한줄출력하는모듈 • 파일의내용을출력하기전에함수printhead()를호출하여제목을출력 • 파일포인터f를이용하여함수feof()을이용하며, 파일내용의형태를알고있으므로함수fscanf()를이용하여각자료형으로자료를입력 • 입력받은자료는함수fprintf()를이용하여적절한형태로출력 • 파일을함수fopen()을이용하여열었으면, 잊지말고함수fclose()를이용하여닫는프로그래밍습관을 기르도록 printhead(); while (!feof(f)) { //파일"grade.txt"에서읽기 fscanf(f, "%d %s %d %d\n", &cnt, names, &point1, &point2); //표준출력에쓰기 fprintf(stdout, "%6d%18s%8d%8d\n", cnt, names, point1, point2); }
예제 소스 • 목적 • 도스명령어type와같은프로그램을만들어보자. • 이프로그램은프로그램이름을list로하여“list filename”을입력하면파일filename의내용을표준출력으로출력하는프로그램 • 조건 • 명령어줄인자를활용, 두번째인자가파일이름에해당 • 이파일이름에해당하는인자를기술하지않으면간단한사용법을알리고프로그램은종료 • 파일내용의출력은한줄마다맨앞에줄번호를출력 • 첫실행에서는파일이름을입력하지않았고, 두번째에는이프로그램의소스를파일이름으로기술
구현 • 명령어줄인자가2개가아니면사용법을출력하고종료 • 명령어줄인자에서두번째인자인argv[1]을가지고파일 열기 • 파일을여는데문제가있으면프로그램을종료 if (argc != 2) { printf("사용법: list filename\n" ); exit(1); }; if ((f = fopen(argv[1], "r")) == NULL) { printf( "파일이열리지않습니다.\n" ); exit(1); };
구현 • 처음줄에줄번호를출력하고, fgetc(f)를이용하여파일f에문자를하나하나읽어, 그읽은문자ch를putchar(ch)를이용하여표준출력으로출력 • 아래소스의putchar(ch)는putc(ch, stdout)로도가능 • 출력된문자가개행문자이면새로운줄이시작되므로줄번호를출력 • 이러한정수를출력하는부분에서는함수printf()를이용 • 프로그램의마지막에는잊지말고파일을닫음 printf("%4d: ", ++cnt); while ((ch = fgetc(f)) != EOF) { putchar(ch); if (ch == '\n') { printf("%4d: ", ++cnt); }; } printf("\n"); fclose(f);
예제 소스 • List.c • 이프로그램은프로그램이름을list로하여“list filename”을입력하면파일filename의내용을표준출력으로출력하는프로그램
텍스트파일과이진파일 • 텍스트 파일 • 함수fprintf()와fscanf()는자료의입출력을텍스트모드로처리 • 텍스트파일은텍스트편집기(에디터)로그내용을알수있으며, 텍스트파일의내용은모두지정된문자코드(일반적으로아스키코드) 값을갖고있어, 그내용을확인할수있을뿐만아니라인쇄가 가능 • 함수fprintf()를이용하여정수형변수cnt에저장된값을파일f에출력하는과정 • 함수fprintf()를이용하여실제정수int형변수cnt를출력하면, 실제적으로파일에저장되는자료는정수값인10에해당하는각문자의아스키값을저장 • 그러므로함수fprintf()를이용하여출력하면, 파일f에는정수값10에해당하는각각의문자‘1’과‘0’의아스키코드값이저장 • 이진 파일 • 이러한텍스트파일과는다르게이진(binary) 파일은C 언어의자료형을모두유지하면서바이트단위로저장하는파일 • 이진파일의대표적인예가실행파일, 이러한이진파일은일반편집기로는그내용확인 불가능
함수fwrite와fread • 이진 파일 처리 • 이와는다르게이진(binary) 모드로입출력을처리하려면함수fwrite()와fread()를이용 • 함수fwrite()는헤더파일stdio.h에다음과같은함수원형으로정의 • 이진파일에저장되어있는자료형을입력하는함수fread() • 각각의인자는출력함수fwrite()와동일 • 인자와 반환 값 • 인자 • 첫번째인자는출력될자료의주소값이며, • 두번째인자는출력될자료의바이트크기이고, • 세번째인자는출력될단위자료의묶음개수이고, • 마지막인자는출력될파일포인터 • 반환값값은파일에출력된단위자료형의개수 • void * • 위에서첫번째인자의자료형이void *로 모든자료형의포인터를대신할수있는포인터변수 size_t fwrite(const void *, size_t, size_t, FILE *); size_t fread(void *, size_t, size_t, FILE *);
이진 파일 입출력 이해 • 함수fwrite()를이용하여정수형변수cnt 값을파일f에출력하는과정 • 함수fwrite()는바이트단위로원하는블록을파일에출력하기위한함수 • 함수fwrite()에의하여출력된자료는함수fread()를이용하여입력해야그자료유형유지가 가능
예제 소스 • Scorefile.c • 학생의성적정보를다음과같이구조체로표현하고, 표준입력으로여러명의자료를입력받아구조체자료형에저장하여파일“score.bin”에저장하는프로그램을작성 • 구조체personscore는번호, 이름, 중간, 기말, 퀴즈점수를멤버로가지며 • 이에 대한 정의는 헤더파일 score.h로
구현 • 이구조체자료형으로한학생의정보를저장하기위하여, 표준입력으로번호를제외한이름, 중간, 기말, 퀴즈점수를입력 • 표준입력은사람마다한행씩받으며, 입력된학생수로학생번호를입력 • 표준입력은한행마다fgets()를이용하여하나의문자열로받고, 이입력된문자열에서각구조체의멤버자료를추출 • 문자열에서자료를추출하기위하여함수sscanf()를이용 • 함수sscanf()는문자열로부터자료를입력받는함수 printf("이름과성적(중간, 기말, 퀴즈)을입력하세요.\n" ); fgets(line, 80, stdin); while (!feof(stdin)) { //표준입력의한줄을구조체의멤버별로자료를입력 sscanf(line, "%s %d %d %d", score.name, &score.mid, &score.final, &score.quiz); score.number = ++cnt; fwrite(&score, sizeof(pscore), 1, f); fgets(line, 80, stdin); }
예제 소스 • Readscorefile.c • 이전에만들었던이진파일score.bin 파일의내용을읽어표준출력으로출력하는프로그램 • 이전의헤더파일score.h 파일은그대로이용하고, 출력형태는다음과같은결과
구현 • 이진파일을읽기위하여읽기모드“r”로파일열기 • 이진자료를읽기위하여함수fread()를이용 • 함수fread()에서첫인자는읽은자료를저장할구조체변수score의주소값을기술 • 함수feof()을이용하여파일의마지막까지구조체자료를읽어적당한출력형태가되도록함수fprintf()를이용하여출력 if ((f = fopen(fname, "r")) == NULL) { printf( "파일이열리지않습니다.\n" ); exit(1); }; fread(&score, sizeof(pscore), 1, f); while (!feof(f)) { //표준출력에쓰기 fprintf(stdout, "%6d%18s%8d%8d%8d\n", score.number, score.name, score.mid, score.final, score.quiz); fread(&score, sizeof(pscore), 1, f); }
파일 내부 위치 • 파일 위치 포인터 • 파일을 열면 항상 파일 위치 포인터(file pointer)라는 것이 파일의 한 장소를 가리킴 • 여기에서의 파일 위치 포인터는 변수에서의 파일 포인터와는 다른 것으로 파일 내부를 바이트 단위로 파일 내부 위치를 나타내는 값 • 파일 포인터가 100L이라면 파일의 처음에서부터 100바이트 떨어진 위치에 현재 파일 포인터가 위치 • 파일 포인터 값은 일반적으로 자료형 long으로 취급하므로 상수를 기술할 때 100L처럼 수 뒤에 L을 기술 가능 • 파일 포인터는 파일 내부에서 자료를 읽거나 쓰는 만큼 파일의 현재 위치에서 뒤로 이동 • 순차적, 임의 접근 • 파일에서 원하는 장소로 자유롭게 이동하는 것을 임의 접근(Random Access) • 파일의 임의 접근을 처리하기 위해서는 파일 포인터를 자유 자재로 이동하는 함수 fseek()이 필요
기호 값 의미 SEEK_SET 0 파일의 시작 위치 SEEK_CUR 1 파일의 현재 위치 SEEK_END 2 파일의 끝 위치 함수 fseek() • fseek() • 함수 fseek()는 함수 원형이 헤더파일 stdio.h 파일에 정의 • 함수 fseek()는 파일 fptr에서 기준점 mode에서 offset만큼 떨어진 곳으로 파일 포인터를 위치하는 함수 • offset • 함수 fseek()에서 두 번째 인자는 long 유형으로 기준점으로부터 떨어진 값을 말하며 흔히 오프셋(offset)이라 함 • 함수 fseek()에서 세 번째 인자는 정수형 기호 상수로 다음 세 가지 중의 하나를 이용 int fseek(FILE *fptr, long offset, int mode)
기준 세가지 • 함수 fseek(f, 100L, SEEK_SET)의 호출은 파일 포인터를 파일의 처음 위치에서 100바이트 떨어진 위치로 이동시킨다. • 함수 fseek(f, 100L, SEEK_CUR)의 호출은 파일 포인터를 파일의 현재 위치에서 100바이트 떨어진 위치로 이동시킨다. • 함수 fseek(f, -100L, SEEK_END)의 호출은 파일 포인터를 파일 끝 위치에서 앞으로 100바이트 떨어진 위치로 이동시킨다.
함수 기능 int fseek(FILE *, long, int) 파일 포인터를 세 기준점으로부터 오프셋만큼 이동하는 함수 long ftell(FILE *) 파일의 현재 파일 포인터를 반환하는 함수 void rewind(FILE *) 파일의 현재 포인터를 0 위치(파일의 시작점)로 이동하는 함수 파일 관련 여러 함수 • 함수 fseek()에서 두 번째 인자는 세 번째 인자인 기준점으로부터 떨어진 값을 말하며, 양수는 뒤, 음수는 앞으로 방향을 지시 • 파일 포인터와 관련된 함수로서 다음 세 가지 함수를 이용 • 함수 ftell()은 인자인 파일의 파일 포인터를 반환하며 • 함수 rewind()는 파일 포인터를 무조건 제일 앞으로 이동
예제 소스 • Appendscore.c • 바로이전에작성한readscorefile.c 프로그램을발전시켜더많은학생의성적정보를추가하는프로그램을작성 • 프로그램이실행되면제일먼저파일score.bin 파일에있는학생정보를모두읽어와출력 • 파일에있는마지막학생정보로부터마지막학생번호를알아냄 • 이번호에1씩증가시키면서다음에추가될학생의번호로이용 • 추가되는자료는이전의학생정보를입력하는방식과동일하게한줄에한명의학생정보를입력
구현 • 추가될학생정보는위와같이학생마다한행씩자료를받아서파일score.bin 파일에저장 • 키ctrl + z를누르면입력이종료되고, 다시파일score.bin에서모든자료를읽어모든정보를출력 • 프로그램에서제일먼저자료를추가할score.bin 파일을모드“a+”로연다. • 파일을“a+”로여는이유는학생정보를추가도하고, 다시읽기도하기위함 • 이프로그램에서는파일score.bin을한번열고, 프로그램종료시에닫도록 • 파일에저장된정보를출력하기위해함수printscore()를만들어호출한다. if ((f = fopen(fname, "a+")) == NULL) { printf( "파일이열리지않습니다.\n" ); exit(1); }; printscore(f);
구현 • 모든정보를출력하면파일포인터는파일끝에 위치 • 학생정보의마지막자료를구조체변수score에저장하기위하여함수fseek()을다음과같이이용 • 다음에는학생정보를추가하는함수appendscore()를호출하고 • 이어서다시모든자료를출력하는함수printscore()를호출하고파일을닫음 offset = (long) sizeof(pscore); fseek(f, -offset, SEEK_CUR); fread(&score, sizeof(pscore), 1, f); //제일마지막자료의번호를찾기위하여 cnt = score.number; printf("\n제일마지막번호가%d번입니다. \n\n", cnt); fseek(f, 0L, SEEK_END); appendscore(f, cnt); printscore(f); fclose(f);
구현 • 함수printscore()에서는읽을파일을인자로처리하고, • 파일을처음부터읽어야하므로함수rewind()를호출하여파일포인터를0으로지정 void printscore(FILE *f) { pscore score; rewind(f); printhead(); fread(&score, sizeof(pscore), 1, f); while (!feof(f)) { … } … }
입출력 함수 • 여러 입출력 함수
기능 함수원형 파일삭제 int remove(const char *) 파일이름바꾸기 int rename(const char *, const char *) 파일삭제, 이름바꾸기 • 함수remove() • 지정된특정한파일을삭제하고 • 함수remove()는remove(“sample.txt”)와같이문자열로지정된파일을삭제 • 함수rename() • 지정된파일의이름을새로운이름으로바꾸는역할을수행 • 함수rename()은rename(“oldname.txt”, “newname.txt”)과같이앞의파일이름을뒤파일이름으로바꾸는역할 • 함수remove()와rename()도헤더파일stdio.h에그함수원형이정의
예제 소스 • filepro.c • 이프로그램은옵션과파일이름을명령어줄인자로처리하는프로그램으로옵션에따라다음과같은기능을수행하도록프로그램 • 첫번째옵션은다음과같이–c로 • 인자인파일이름으로파일을생성하는기능을수행 • 이파일filename은기존에없으면새로생성하고, 만일있으면있는파일을이용 • 파일에는이명령어를수행한횟수를함수getw()를이용하여파일에저장하는기능을수행 >fileproc –c filename • 두번째옵션은–d를이용하며 • 지정된파일filename을삭제한다. >fileproc –d filename • 세번째옵션은–n를이용하며 • 지정된파일filename1을새로운이름filename2으로수정 >fileproc –n filename1 filename2
결과 • 다음은이프로그램을명령어프롬프트에서실행한결과 • 이프로그램에서옵션–d는함수remove()를이용하여삭제하고, • 옵션–n은함수rename()을이용하여파일이름을수정
구현 • 위프로그램에서옵션–c는지정된파일에옵션–c를실행한횟수를출력 • 이를위하여실행시에파일에서이전에저장한정수를getw() 함수로읽어와1을더하여함수putw()를이용하여다시그파일에저장 • 파일이없는경우에는새로이파일을만들어서1을저장 • 명령어줄인자에서옵션에저장된문자열은argv[1] • 다음소스와같이옵션에따라변수mode에적당한값을저장 if (strcmp(argv[1], "-c") == 0) { mode = 1; } else if (strcmp(argv[1], "-d") == 0) { mode = 2; } else if (strcmp(argv[1], "-n") == 0) { mode = 3; };
구현 • 다음은옵션이–c인경우 • 이전에파일이있으면, 모드“r+”로파일을열고, 이전에파일이없으면모드“w+”로파일을여는모듈 switch (mode) { case 1: if ((f = fopen(argv[2], "r+")) == NULL) { if ((f = fopen(argv[2], "w+")) == NULL) { printf( "파일이열리지않습니다.\n" ); exit(1); } }; …
구현 • 다음소스는이전에사용한파일은파일크기가0이아니므로, 그파일에서맨앞의정수하나를함수getw()를이용하여읽어오는모듈 • 다음은변수cnt에는이전의횟수가저장되어있으므로1을더한++cnt를파일의맨앞부분에함수putw()를이용하여다시출력 fseek(f, 0L, SEEK_END); if (ftell(f) != 0) { fseek(f, 0L, SEEK_SET); cnt = getw(f); } fseek(f, 0L, SEEK_SET); putw(++cnt, f); printf("-c 옵션을파일%s에%d번사용했습니다.\n", argv[2], cnt); fclose(f); break;
구현 • 다음은 옵션이 –d인 경우 • remove(argv[2]) 함수를 호출하여 파일을 삭제 • 다음은옵션이-n인경우 • rename(argv[2], argv[3]) 함수를호출하여파일이름을수정 case 2: remove(argv[2]); break; case 3: if (argc != 4) { printf("사용법: -[c,d,n] filename\n" ); exit(1); }; rename(argv[2], argv[3]); break;
프로그램 연습 • 프로그램 목적 • 이장에서배운함수들을이용하여score.bin 파일에서학생번호를이용하여학생정보를검색하는프로그램을작성 • 헤더파일score.h를그대로이용하고, • 함수printscore()와printhead()를그대로이용하며, • 함수searchscore()를만들어검색에이용 • 프로그램은다음조건을만족하도록 • 제일 먼저 score.bin 파일에 있는 모든 정보를 출력하자. • 가장 큰 학생 번호를 출력하여 잘못된 학생번호를 입력하지 않도록 한다. • 검색할 학생번호를 입력 받는다. • 검색 함수 searchscore(FILE *f, int cnt)는 두 개의 인자를 가지며, 두 번째 인자가 검색할 학생 번호이다. • 검색 결과를 출력한다.