>

다양한 명령 줄 인수를 취하는 프로그램이 있습니다. 단순화를 위해 3 개의 플래그가 필요하다고 말할 것입니다. -a-b , 다음 코드를 사용하여 내 인수를 구문 분석하십시오.

-c

참고 : a 및 b는 플래그 뒤에 매개 변수를 사용합니다.

하지만 프로그램을 호출하면 문제가 발생합니다

   int c;
    while((c =  getopt(argc, argv, ":a:b:c")) != EOF)
    {
        switch (c)
        {
             case 'a':
                 cout << optarg << endl;
                 break;
             case 'b':
                 cout << optarg << endl;
                 break;
             case ':':
                 cerr << "Missing option." << endl;
                 exit(1);
                 break;
        }
    }

여기서 parameterForA를 잊어 버린 경우 parameterForA (optarg로 표시)는 ./myprog -a -b parameterForB 로 반환됩니다.  parameterForB는 매개 변수가없는 옵션으로 간주되며 optind는 argv에서 parameterForB의 색인으로 설정됩니다.

이 상황에서 바람직한 행동은 -b 입니다.   ':' 에 대한 인수가 없으면 리턴됩니다. 및 -a  표준 오류로 인쇄됩니다. 그러나 그것은 Missing option. 경우에만 발생합니다  프로그램에 마지막으로 전달 된 매개 변수입니다.

질문은 다음과 같습니다. -a 를 만드는 방법이 있습니까?   getopt() 로 시작하는 옵션이 없다고 가정 ?

-
  • 답변 # 1

    getopt 에 대한 POSIX 표준 정의를 참조하십시오 .

    와이즈 비즈

    그 탐지에 관해서는

    와이즈 비즈

    와이즈 비츠 같아  원하는 것을 수행하지 않기 위해 정의되었으므로 직접 확인을 구현해야합니다. 다행히도

    If it [getopt] detects a missing option-argument, it shall return the colon character ( ':' ) if the first character of optstring was a colon, or a question-mark character ( '?' ) otherwise.

    를 검사하여 그렇게 할 수 있습니다  그리고

      If the option was the last character in the string pointed to by an element of argv, then optarg shall contain the next element of argv, and optind shall be incremented by 2. If the resulting value of optind is greater than argc, this indicates a missing option-argument, and getopt() shall return an error indication.

      Otherwise, optarg shall point to the string following the option character in that element of argv, and optind shall be incremented by 1.

    를 변경  너 자신.

    getopt
    
    

  • 답변 # 2

    C ++로 작업하는 경우 boost :: program_option은 명령 줄 인수를 구문 분석하는 것이 좋습니다.

    부스트 :: program_options 라이브러리

  • 답변 # 3

    전체 공개 : 저는이 문제에 대해 전문가가 아닙니다.

    gnu.org의이 예제를 사용할 수 있습니까? '?'를 처리하는 것 같습니다 예상 인수가 제공되지 않은 경우 문자 :

    *optarg
    
    

    업데이트 :아마도 다음과 같은 해결책이 있습니까?

    optind
    
    

  • 답변 # 4

    부스트 프리 프로젝트의 대안으로 int c, prev_ind; while(prev_ind = optind, (c = getopt(argc, argv, ":a:b:c")) != EOF) { if ( optind == prev_ind + 2 && *optarg == '-' ) { c = ':'; -- optind; } switch ( … 를위한 간단한 헤더 전용 C ++ 래퍼가 있습니다.  (BSD 3-Clause 라이센스하에) : https://github.com/songgao/flags.hh

    while ((c = getopt (argc, argv, "abc:")) != -1) switch (c) { case 'a': aflag = 1; break; case 'b': bflag = 1; break; case 'c': cvalue = optarg; break; case '?': if (optopt == 'c') fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; default: abort (); } 에서 가져온

     저장소에서 :

    while((c =  getopt(argc, argv, ":a:b:c")) != EOF)
    {
        if (optarg[0] == '-')
        {
            c = ':';
        }
        switch (c)
        {
            ...
        }
    }
    
    

  • 답변 # 5

    getopt 에는 상당히 다른 버전이 있습니다  한 버전에서 작동하도록해도 해결 방법이 중단 될 수있는 다른 버전이 5 개 이상있을 수 있습니다. getopt를 사용해야하는 압도적 인 이유가 없다면 Boost.Program_options와 같은 다른 것을 고려할 것입니다.

    example.cc

관련 자료

  • 이전 python - heapqnlargest는 어떻게 작동합니까?
  • 다음 css : Twitter Bootstrap에서 입력 및 텍스트 영역 요소의 테두리 /윤곽선 색상을 변경하려면 어떻게해야합니까?