8.9 main() 함수의 매개변수 함수의 매개변수는 일반함수뿐만 아니라, main() 함수에도 적용된다. 왜냐면 운영체제의 입장에서 main()은 하나의 함수에 지나지 않기 때문이다. 따라서 main() 함수는 운영체제와 파일정보 및 자료를 전달하기 위하여 매개변수를 사용할 수 있다.
■ 매개변수 argv와 argc main() 함수의 형식매개변수는 두개의 변수 argc와 argv로 구성된다. main(int argc, char *argv[]) argc는 운영체제 상에서 main() 함수를 실행하기 위하여 커맨드 라인(command line)에 작성되는 문자열의 수를 나타내고, argv는 문자열들을 가리키는 포인터 변수이다. main() 함수의 실매개변수는 커맨드 라인에서 실행 파일명 뒤에 작성되는 문자열들이다. main(int argc, char *argv[]) { int i; int n, x=0; if (argc!=4) /* 커맨드 라인의 문자열 수를 검사 */ exit(1); /* 프로그램 종료 */ for (i=0; i<argc; i++) printf("%s ", argv[i]); /* argv의 문자열 출력 */ n=atoi(argv[3]); /* 네번째 문자열을 정수로 전환*/ for (i=0; i<n; i++) x=x+i; printf("%d ", x); } 예를 들면 프로그램 실행파일 test가 두개의 입출력 파일 ein과 aus 그리고 한 개의 정수자료를 필요로 한다면, 운영체제 모드에서 라인 커맨드는 "/test ein aus 10"와 같이 작성해야 한다. 그러면 main() 함수의 매개변수 argc는 4가 되고, argv[]에서 argv[0]="test", argv[1]="ein", argv[2]="aus", argv[3]="10"의 값을 갖게 된다. ■ 외부 파일을 main() 함수에 전달하는 방법 첫째, 디스크에 있는 물리적 파일을 프로그램의 논리적 파일로 사용하기 위해서 main() 함수의 매개변수를 main(int argc, char *argv[])처럼 서술한다. 둘째, 매개변수로 전달된 물리적 파일에 대응하는 논리적 스트림 파일을 FILE로 선언한다. FILE *<논리적 파일명> [,*<논리적 파일명>]...; FILE *fopen(); 셋째, 물리적 파일을 사용목적에 맞도록 열고(open), 함수 fopen()을 통하여 프로그램의 논리적 파일과 관계를 맺도록 서술한다. 1) <논리적 파일명>=fopen( <물리적 파일명>, "<mode>"); 2) <논리적 파일명>=fopen("<물리적 파일명>", "<mode>"); fopen() 함수는 파일을 열 때 실패하면, NULL 값을 반환한다. 1) 형식은 파일을 main() 함수의 매개변수를 통하여 전달할 때 사용되고, 2) 형식은 main() 함수의 매개변수를 통하지 않고 프로그램에서 직접 파일을 참조할 때 사용된다. 넷째, 파일 입출력문으로 자료를 처리한 후에는 열어둔 모든 파일을 fclose() 함수로 반드시 닫아야 한다. fclose (<논리적 파일명>); 파일을 닫는 의미는 입출력 버퍼에 있는 자료를 모두 입출력 파일에 옮겨 쓰고, 파일 끝에 EOF 표시를 붙힌 후, 버퍼와 파일의 제어블록까지 지워버리는 것을 의미한다. 파일이 성공적으로 닫히면 0 값을 반환하고, 실패하면 -1 값을 반환한다. ■ 입출력 파일의 mode 입출력 파일의 <mode>와 그의 기능은 다음과 같다. "r" : 기존 파일로부터 읽기(read) "w" : 출력할 파일이 없으면 빈 파일을 만들고, 있으면 빈 파일로 만들어 쓰기 "a" : 파일이 없으면 파일을 생성하고, 있으면 파일 끝에 부쳐 쓰기 "r+" : 기존 파일로부터 읽고 쓰기(read/write) "w+": 파일 존재여부를 떠나서 빈 파일을 만들어 읽고 쓰기 "a+" : 파일이 없으면 우선 파일을 생성한 후에 읽고 쓰기 다음 프로그램은 main() 함수의 매개변수를 통하여 파일로부터 읽고 쓰기 위한 과정을 서술하고 있다. /* main() 함수의 매개변수로 프로그램에 연결 */ main(int argc, char *argv[]) { char c; FILE *in_fil, *out_fil, *fopen(); /* 논리 스트림 파일 선언 */ in_fil=fopen(argv[1], "r"); /* 물리적 파일과 논리적 파일의 관계를 연결 */ out_fil=fopen(argv[2], "w"); c=fgetc(in_fil); /* 파일로부터 한 문자 읽기 */ .............. fclose(in_fil); fclose(out_fil); } 다음은 main() 함수에서 매개변수를 사용하지 않고 /usr/ 디렉토리에 있는외부파일 data_in, data_out을 논리파일 in_file과 out_fil에 input과 output용으로 직접연결하는 예이다. main(void) { char c; FILE *fopen(); FILE *in_fil, *out_fil; if ((in_fil=fopen("/usr/data_in", "r")==NULL) /* 실패하면 */ { printf("cannot open file for read!"); exit(); } ........ out_fil=fopen("/usr/data_out", "w"); c=fgetc(in_fil); /* 파일로부터 문자 읽기 */ ........ fclose(in_fil); /* 파일 닫기 */ fclose(out_fil); } 다음은 파일로부터 학생들의 성적을 읽고 처리하는 프로그램으로서 자료구조는 구조체에 대한 배열로 정의했으며, 외부의 입출력 파일은 main() 함수의매개변수를 통하여 프로그램에 연결하였다. #include <stdio.h> struct student { int id; /* stud ent_id; */ char name[10]; /* student_name; */ int nat, eng, math; float aver; } tp[10]; struct student *pt; main(int argc, char *argv[]) { FILE *infil, *outfil, *fopen(); /* 논리 스트림 파일 선언 */ infil=fopen(argv[1], "r"); /* 물리파일에 대한 논리파일 연결 */ outfil=fopen(argv[2],"w"); pt=tp; /* pt=&tp[0]; */ /* fscanf()와 fprintf()는 파일로부터의 입출력 함수 */ while (fscanf (infil, "%3d", &pt->id)!=EOF) { fscanf(infil, "%10c %3d %3d %3d", pt->name, &pt->nat, &pt->eng, &pt->math); pt->aver=(float)(pt->nat+pt->eng+pt->math) / 3.0; fprintf(outfil, "%3d %13s %6d %6d %6d %7.2f \n", pt->id, pt->name, pt->nat, pt->eng, pt->math, pt->aver); ++pt; } fclose (infil); fclose (outfil); } |