C언어 프로그램 실행 인수 정보 구하는 함수 getopt()

2020. 3. 14. 10:33 컴퓨터/프로그래밍

C함수 프로그램 실행 인수 정보 구하기 getopt()

프로그램 실행 시 입력 받은 인수를 분석합니다.

  • 헤더: unistd.h
  • 형태: int getopt (int argc, char *const *argv, const char *shortopts)
  • 인수: int argc 인수의 개수
    char *const *argv 인수의 내용
    const char *shortopts 검색하려는 옵션들의 문자열
  • 반환: int 찾아진 옵션 문자를 반환하거나 지정이 안된 옵션이 있으면 '?'를, 더 이상 옵션이 없으면 -1을 반환
caution

프로그램을 실행하면서 컴파일러처럼 다양한 옵션을 인수로 받는다면 각 옵션별로 존재하는지, 옵션에 따라 지정된 데이터가 있는지 확인하기 위해서는 getopt()가 매우 편리합니다.

또한 getopt()는 함수 외에도 관련 광역변수의 역활도 아울러 알아야 합니다.

  • extern char *optarg : 인수를 필요하는 옵션을 처리할 때 필요한 인수 포인터
  • extern int optind : 아직 처리하지 못한 인수를 가르킴
  • extern int opterr : 에러 문자열 출력 여부를 결정. 0 이면 출력 안 함
  • extern int optopt : 지정되지 않은 옵션으로 분류되었을 때, 실제 옵션 문자

실행 옵션 관련 함수

  • getopt() : '-'로 시작하는 짧은 이름의 옵션을 검색합니다.
  • getopt_long() : 짧은 이름의 옵션과 '--'로 시작하는 긴 이름의 옵션을 검색합니다.
  • getopt_long_only() : getopt_long()처럼 긴 이름의 옵션을 검색하며, 차이라면 '-'를 짧은 이름 옵션뿐만 아니라 긴 이름 옵션에도 사용할 수 있습니다.

예제

#include <stdio.h>
#include <unistd.h>

int main( int argc, char **argv)
{
   int   is_f      = 0;
   int   is_o      = 0;
   int   is_r      = 0;
   char *file_name = NULL;
   int   param_opt;

   while( -1 !=( param_opt = getopt( argc, argv, "f:or"))) {
      switch( param_opt) {
      case  'f'   :  is_f  = 1;
                     file_name   = optarg; // optarg 사용
                     break;
      case  'o'   :  is_o  = 1;
                     break;
      case  'r'   :  is_r  = 1;
                     break;
      case  '?'   :  printf( "알 수 없는 옵션: %c\n", optopt); // optopt 사용
                     break;
      }
   }
   if ( is_f && ( NULL != file_name))    printf( "옵션 -f 파일 이름 : %s\n", file_name);
   if ( is_o)  printf( "옵션 -o 있음\n");
   if ( is_r)  printf( "옵션 -r 있음\n");

   return 0;
}

프로그램을

]$ ./a.out -f badayak -o -a

로 실행했다면 -f 에 대한 옵션을 사용했다는 것을 알 수 있고 -f 에 대한 문자열을 badayak로 구합니다. 또한 -o 옵션이 사용되었음을 확인할 수 있지만 -a 는 알 수 없는 옵션으로 분류됩니다.

실행 결과

]$ ./a.out  -f badayak -o -a
./ss: invalid option -- a    <-- 프로그램 실행시 리눅스에서 출력하는 에러 메시지
알 수 없는 옵션: a
옵션 -f 파일 이름 : badayak
옵션 -o 있음
]$

보시는 바와 같이 프로그램 실행 시 다양한 옵션을 처리해야 한다면 getopt()를 사용하면 쉽게 옵션을 처리할 수 있습니다.

-a는 유효하지 않는 옵션이라고 에러 메시지를 출력하고 있습니다. getopt()를 호출하기 전에 opterr을 0으로 설정하고 다시 실행해 보겠습니다.

   opterr   = 0; // opterr 사용. 에러 내용을 출력 off
   while( -1 !=( param_opt = getopt( argc, argv, "f:or")))
   {
             위 프로그램과 동일
   }

실해하면 시스템에서 발생하는 에러 메시지를 출력하지 않습니다.

]$ ./a.out -f falinux -o -a
./ss: invalid option -- a    <-- 이 부분이 출력되지 않습니다.
알 수 없는 옵션: a
옵션 -f 파일 이름 : falinux
옵션 -o 있음 
]$

이번에는 optind를 알아 보겠습니다. 저는 optind를 opt index의 줄임말로 이해하고 있습니다. 인수로 받은 문자열 중에 처리하지 못한 인수에 대한 인덱스 번호를 차례로 반환해 줍니다.

#include <stdio.h>
#include <unistd.h>

int main( int argc, char **argv)
{
   int   param_opt;

   opterr   = 0;
   while( -1 !=( param_opt = getopt( argc, argv, "f:or")))
   {
      switch( param_opt)
      {
      case  'f'   :  printf( "check 'f'n");
                     printf( "f: %sn", optarg);
                     break;
      case  'o'   :  printf( "check 'o'n");
                     break;
      case  'r'   :  printf( "check 'r'n");
                     break;
      case  '?'   :  printf( "알 수 없는 옵션: %cn", optopt);
                     break;
      }
   }

   printf( "nn체크에 제외된 인수 목록 :n");
   while( optind < argc)
      printf( "    %sn", argv[optind++]);

   return 0;
}  

]$ ./a.out -f jwmx -o badayak -r com

으로 실행해 보겠습니다. -f jwmx -o 까지는 옵션 처리를 합니다. 그 다음 문자열인 badayak는 - 로 시작하지 않기 때문에 유효하지 않은 인수로 분류되지 않고 인수 분류에서 제외 되면, badayak의 순서 번호를 optind 값에 대입됩니다.

다시 -r 옵션이 처리되고 역시 com 문자열은 인수 분류에서 제외됩니다. 그러므로 optind값을 증가하면서 값을 확인하면 옵션 분류에서 제외된 문자열을 차례로 구할 수 있습니다.

]$ ./a.out -f jwmx -o badayak -r com -a
check 'f'
f: jwmx
check 'o'
check 'r'
알 수 없는 옵션: a


체크에 제외된 인수 목록 :
    badayak
    com
]$


이 댓글을 비밀 댓글로