출처 - http://www.devblog.kr/r/8y0gFPAvJ2p9ZANhTI6uJa8XI4jchsrnl9oswwCKNR9D0xIIeR
C프로그램의 파라미터 파싱 및 처리
문자열 파싱은 스크래치 상태(아무것도 없는 빈 상태)로부터 구현하기가 만만치 않은데, 이를 도와주는 라이브러리 함수가 있으니 바로 unistd.h
에 정의된 getopt()
함수이다.
getopt()
이 함수의 원형은 다음과 같다.
int getopt(int argc, char * const argv[], const char *optstring);
이 함수의 파라미터는 간단한다.
- argc, argv :
main()
함수가 받은 파라미터를 그대로 전달한다. - optstring : 파싱해야 할 파라미터를 쓴다. 옵션이 별도의 파라미터를 받는 경우 콜론을 함께 쓴다.
예를 들어 -h
, -v
, -f filename
을 받는 세 가지 옵션이 있다고 하면 옵션스트링은 "hvf:"
가 된다. 각각의 옵션을 파싱해내기 위해서는 getopt()
함수가 0을 리턴할 때까지 계속해서 반복하면 된다.
그외 전역변수
이 함수와 관련된 전역 변수에는 다음과 같은 것들이 있다.
- optarg : 옵션 뒤에 별도의 파라미터 값이 오는 경우, 이를 파싱한 결과 파라미터 값은 optarg에 문자열로 저장된다.
- optind : 다음번 처리될 옵션의 인덱스이다. 만약 파싱한 옵션이후에 추가적인 파라미터를 받는다면 (예를 들어 입력 파일 이름 같이) 이 값을 활용할 수 있다. getopt()함수는 한 번 호출될 때마다 이 값을 업데이트한다.
- opterr : 옵션에 문제가 있을 때, 이 값은 0이 아닌 값이되며, getopt()함수가 메시지를 표시하게 된다.
- optopt : 알 수 없는 옵션을 만났을 때 해당 옵션이 여기에 들어간다. (이 때 getopt의 리턴값은 ‘?’가 된다.)
샘플 코드
아래 샘플 코드는 간략한 예를 보여준다. 이 코드에서는 a, b, c의 세 옵션을 인식하며 각각의 옵션이 주어지는 경우 해당 플래그 변수를 1로 정의하고 그 결과를 출력한다.
1: #include <stdio.h>
2: #include <unistd.h> // for getopt()
3:
4: int main(int argc, char * const * argv){
5: int flag_a = 0, flag_b = 0, flag_c = 0;
6: int c; // option
7: while( (c = getopt(argc, argv, "abc")) != -1) {
8: // -1 means getopt() parse all options
9: switch(c) {
10: case 'a':
11: flag_a=1;
12: break;
13: case 'b':
14: flag_b=1;
15: break;
16: case 'c':
17: flag_c=1;
18: break;
19: case '?':
20: printf("Unknown flag : %c", optopt);
21: break;
22: }
23: }
24: if(flag_a) {printf("flag a is ON \n");}
25: if(flag_b) {printf("flag b is ON \n");}
26: if(flag_c) {printf("flag c is ON \n");}
27: return 0;
28: }
보통 while
문으로 루프를 돌면서 옵션들을 하나씩 검사한다. getopt가 optstring
으로 정의되지 않은 옵션문자를 만나면 opterr
값이 세팅되고, 동시에 getopt()함수가 해당 문자에 대해 메시지를 출력한다. 이 때 반환값은 '?'
가 되고 이때 알 수 없는 옵션 문자는 optopt
에 저장된다.
추가 파라미터를 필요로하는 옵션
gcc의 -o
와 같이 파일 이름등의 추가 파라미터를 필요로하는 옵션은 다음과 같이 처리한다.
- optsting에서 옵션 문자 뒤에 콜론을 붙인다.
"abcf:"
와 같은 식으로 쓴다. - getopt()함수는
-f
를 만나면 자동으로 그 뒤에 붙은 문자열을 공백까지 탐색하여 이를optarg
에 복사한다. - 처리시에는 리턴값이 ‘f’인 경우
optarg
의 값을 그대로 액세스하면 된다.
이러한 처리 코드는 아래와 같다.
case 'f':
memcpy(file_name, optarg, strlen(optarg));
break;
또한 파라미터가 있다고 정의한 경우, 파라미터 값이 빠진채로 실행되었다면 이 때는 옵션이 인식할 수 없는 옵션으로 처리된다.
case '?':
if(optopt == 'f') {
printf("option -f requires FILENAME\n");
}
break;
optind
옵션문자들을 모두 처리한 이후에 프로그램 자체의 파라미터를 처리하기 위해서는 optind
를 argv
의 인덱스로 사용하여 파라미터를 전달 받을 수 있다.
그외 긴 이름
--output
등의 긴 이름 옵션을 사용하기 위해서는 getoptlong
함수를 사용한다.
'IT > C&C++' 카테고리의 다른 글
[C]문자열을 정수로 변환 :: atoi() (0) | 2016.04.15 |
---|---|
[C] memcmp 두개의 메모리 변수에 대한 내용 비교 (0) | 2016.04.15 |
-펌-[C] system함수, exec계열의 함수(execl, execv, execle, execve, execlp, execvp) (0) | 2016.03.25 |
-펌-[C] abort 함수 설명 밎 사용예제 (0) | 2016.03.25 |
-펌-[C] fork() 함수에 대해서.. (0) | 2016.03.25 |