2016-07-22 4 views
2

을하지 않는 것 (파일이라고 testgetopt.c에 저장) :C : getopt는은() : 옵션이 적용에게 나는 다음과 같은 C 코드를 시도하고

#include <stdio.h> 
#include <stdlib.h> 
#include <getopt.h> 
#include <ctype.h> 

void usage(char *s) 
{ 
    fprintf(stderr, "Usage: %s [-d] -i input-TIFF-file -o output-raw-file\n", s); 
    fprintf(stderr, "Note: -d indicates debugging option\n"); 
} 

int main(int argc, char **argv) { 
    char c; 
    size_t i; 
    char *itext = NULL, *otext = NULL; 
    FILE *fout; 
    short debug = 0; 

    if ((c = getopt(argc, argv, "di:o:")) == EOF) { 
     usage(argv[0]); 
     exit(1); 
    } 

    while ((c = getopt(argc, argv, "di:o:")) != EOF) { 
     switch (c) { 
     case 'd': 
      debug = 1; 
      break; 
     case 'i': 
      itext = optarg; 
      break; 
     case 'o': 
      otext = optarg; 
      break; 
     case '?': 
      if (optopt == 'i' || optopt == 'o') 
       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); 
      usage(argv[0]); 
      exit(1); 
     default: 
      fprintf(stderr, "Both -i and -o are needed\n"); 
      usage(argv[0]); 
      exit(1); 
     } 
    } 
    printf("debug = %i\n", debug); 
    if (debug) 
     printf ("input file = %s, output file = %s\n", itext, otext); 
    return EXIT_SUCCESS; 
} 

내가 사용 컴파일

gcc testgetopt.c 

하지만 -d를 포함하든 그렇지 않든 관계없이 항상 0으로 설정된 디버그를 얻습니다. 프로그램에서 -d 디버그를 1로 설정하고 그렇지 않으면 0으로 설정해야합니다.

무엇이 잘못 되었습니까?

다음은 예입니다

은 우리가 처음 -d 포함 우리가 다음에 해보자없는 -d

./a.out -i in.dat -o out.dat 
debug = 0 

함께 해보자.

./a.out -d -i in.dat -o out.dat 
debug = 0 

도움이나 제안을 보내 주셔서 감사합니다.

+0

어떻게 디버그를 시도 했습니까? 루프 내에서 getopt의 결과를 출력하면 어떤 일이 벌어지고 있는지에 대한 이론을 세울 수 있습니다. 일종의 stack-overflower가 그 일을 충분히 해냈습니다. –

답변

3

문제는 정상적인 검사로 getopt을 호출하고 성공했을 때 그 결과를 사용하지 않는 것이 문제입니다. 즉 첫 번째 옵션은 항상 폐기됩니다. 당신은 쉽게 아닌 첫 번째 옵션으로 -d을 넣어이를 확인 할 수 있습니다

$ ./a.out -i in.dat -o out.dat -d 
debug = 1 
input file = (null), output file = out.dat 

당신은 -d 효과 이번에하지만 첫 번째 인수 -i이 설정되어 있지을 한 것을 볼 수 있습니다.

해결 방법에는 여러 가지가 있습니다. 권장되는 방법 (IMHO)은 첫 번째 getopt 통화를 삭제하는 것입니다. 그런 다음 온 전성 검사를 변경하여 실제 옵션을 확인하십시오. 즉, 모든 필수 옵션이 제공되었는지를 확인하는 코드 인 getopt 루프가 있어야합니다. 예를 들어

: 당신은 두 번 getopt를 호출하기 때문에

int main(int argc, char **argv) { 
    char c; 
    size_t i; 
    char *itext = NULL, *otext = NULL; 
    FILE *fout; 
    short debug = 0; 

    /* REMOVED THIS BLOCK OF CODE 
    if ((c = getopt(argc, argv, "di:o:")) == EOF) { 
     usage(argv[0]); 
     exit(1); 
    } 
    */ 

    while ((c = getopt(argc, argv, "di:o:")) != EOF) { 
     switch (c) { 
     case 'd': 
      debug = 1; 
      break; 
     case 'i': 
      itext = optarg; 
      break; 
     case 'o': 
      otext = optarg; 
      break; 
     case '?': 
      if (optopt == 'i' || optopt == 'o') 
       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); 
      usage(argv[0]); 
      exit(1); 
     default: 
      fprintf(stderr, "Both -i and -o are needed\n"); 
      usage(argv[0]); 
      exit(1); 
     } 
    } 

    /* ADD SOME ARGUMENT SANITY CHECKS */ 
    if (!itext || !otext) { 
     printf("Missing mandatory arguments\n"); 
     exit(1); 
    } 

    printf("debug = %i\n", debug); 
    if (debug) 
     printf ("input file = %s, output file = %s\n", itext, otext); 
    return EXIT_SUCCESS; 
} 
+0

죄송합니다. 이해가 안됩니다. "그런 다음 실제 옵션을 확인하기 위해 온 전성 검사를 변경하십시오. 즉 모든 필수 옵션이 제공되었는지 확인하는 getopt 루프 다음에 코드가 있어야합니다." 참조/예를 제공해 주시겠습니까? 감사! – user3236841

+0

초기 getopt 검사를 제거하고 명령 행 구문 분석 후에 몇 가지 온 전성 검사를 추가하는 예제 코드를 추가했습니다. 온 전성 검사는 단지 예일 뿐이므로 점검 할 다른/다른 요구 사항이있을 수 있습니다. – kaylum

+0

Btw, "기본값"이 작동하지 않는 이유는 무엇입니까? – user3236841

1

, 당신은 호출 사이 optind = 1;를 재설정해야합니다.

+0

감사합니다. 하지만 두 번 호출하지 않는 방법을 알고 싶습니다! – user3236841

+0

맞아, 진짜 대답은'getopt()'를 두 번 호출하지 않는 것이다. @ Kaylum의 대답은 그것을하는 방법에 대한 몇 가지 좋은 조언을 제공합니다 – John3136

+0

나는 두 답을 모두 점검하는 것 같지 않습니다! 하나를하는 것은 다른 사람의 수표를 빼앗는다! 나는이 주석을 남기고 다른 것을 점검 할 것이기 때문에 그것은 내가 원했던 것보다 더 깊다. 다시 Thx! – user3236841

관련 문제