programing

getopt_long() -- 적절한 사용 방법은 무엇입니까?

powerit 2023. 9. 15. 21:24
반응형

getopt_long() -- 적절한 사용 방법은 무엇입니까?

네, 검색해보니 올바른 방향으로 시작한 StackOverflow 주제가 다음 두 가지 있었습니다.

C/UNIX의 인수 구문 분석 도우미

명령줄에서 C 프로그램으로 인수 전달

참고: 모든 코드는 의사 코드입니다. 작동하면 컴파일 가능한 코드가 게시됩니다.

하지만 C에서 getopt_long()을 사용하는 방법에 대해서는 아직 완전히 혼란스럽습니다.제가 쓰고 있는 프로그램은 다음과 같은 가능한 태그가 있는 것으로 정의됩니다. (그러나 필요한 만큼만 포함할 수 있고 나머지는 빈 값으로 채울 수 있습니다.)

id3tagEd filename -title "title" -artist "artist" -year 1991 -comment "comment" -album "album" -track 1

자, 제가 읽은 바로는 긴 옵션을 위한 구조를 사용해야 합니다. 맞죠?만약 그렇다면, 나는 이 글의 행에 무언가를 썼습니다.

struct fields field =
{
    char *[] title;
    char *[] artist;
    char *[] album;
    int year;
    char *[] comment;
    int track;
}


static struct options long_options[] =
{
    {"title", 0, &field.title, 't'},
    {"artist", 0, &field.artist, 'a'},
    {"album", 0, &field.album, 'b'},
    {"year", 0, &field.year, 'y'},
    {"comment", 0, &field.comment, 'c'},
    {"track", 0, &field.track, 'u'},
    {0, 0, 0, 0}
}

이제, 제가 수집한 바에 따르면, 저는 이것을 통해 그것을 부를 것입니다.

int option_index = 0;

int values = getopt_long(argc, argv, "tabycu", long_options, &option_index);

여기서부터는 현장 구조를 엄격히 사용하고 프로그램 내에서 필요한 일을 할 수 있습니까?하지만, 만약 이것이 사실이라면, 누군가 long_options 구조 전체를 설명할 수 있을까요?맨 페이지 같은 것들을 읽었는데 완전히 혼란스러워요.맨 페이지를 다시 읽음으로써 변수를 null로 설정할 수 있으며 모든 옵션 요구 사항을 "required_argument"로 설정해야 하는지 알 수 있습니다.그리고 나서 잠시 () 루프를 통해 구조물을 설정하는 건가요?하지만 옵타그가 사용되고 있는 것으로 보입니다.getopt_long()으로 설정되어 있습니까?아니면 예시에서 빠진 것입니까?

그리고 마지막 문제는 항상 이름 없는 필수 옵션이 있습니다. filename, argv[0]을(를) 사용하여 액세스할 수 있습니까? (처음이라고 가정할 수 있기 때문에).

참고로, 이것은 숙제 문제와 관련이 있지만, 이것은 그것을 고치는 것과는 아무런 관련이 없으며, 더 근본적인 것은 명령 줄을 통해 C에서 전달되는 인수와 구문 분석을 먼저 이해해야 합니다.

우선, 당신은 아마도 당신이 원하지 않을 것입니다.0를 위해has_arg필드 - 다음 중 하나여야 합니다.no_argument,required_arguemnt, 아니면optional_argument. 당신의 경우, 그들 모두는required_argument. 그 외에, 당신은 당신이 사용하는 것이 아닙니다.flag필드가 정확합니다. 정수 포인터여야 합니다.해당 플래그가 설정되어 있는 경우,getopt_long()당신이 통과한 정수를 통해 그것을 채울 것입니다.val필드. 이 기능은 전혀 필요 없을 것 같습니다.다음은 귀하의 사례에 대한 더 나은 (단축) 예입니다.

static struct option long_options[] =
{
    {"title", required_argument, NULL, 't'},
    {"artist", required_argument, NULL, 'a'},
    {NULL, 0, NULL, 0}
};

그러면 나중에 적절하게 사용할 수 있습니다. (manpage에서 바로 댓글을 달았습니다.)

// loop over all of the options
while ((ch = getopt_long(argc, argv, "t:a:", long_options, NULL)) != -1)
{
    // check to see if a single character or long option came through
    switch (ch)
    {
         // short option 't'
         case 't':
             field.title = optarg; // or copy it if you want to
             break;
         // short option 'a'
         case 'a':
             field.artist = optarg; // or copy it if you want to
             break;
    }
}

필요에 따라 다른 필드로 확장할 수 있습니다(오류 처리를 추가하십시오!).-고 -할우-title그리고.-artist예에서 본 것처럼, 당신은 다음을 사용할 필요가 있을 것입니다.getopt_long_only()선택권이 처럼 말입니다

당신의 것에 관해서는filename선택권이 있다면, 당신은 그것을 A로서 꺼낼 것입니다.'?'getopt_long()그 시간에 처리할 수 있도록 전화해 주세요.다른 옵션은 첫 번째 옵션이나 마지막 옵션 중 하나를 요구하고 개별적으로 처리하는 것입니다.

popt 라이브러리를 사용하면 의사 코드에서 했던 것처럼 똑똑한 것을 만들 수 있습니다.

#include <stdio.h>
#include "popt.h"

struct _field {
    char *title;
    char *artist;
    /* etc */
} field;

field.title = NULL;
field.artist = NULL;

/* HERE IS WHAT YOU WANTED IN YOUR PSEUDO-CODE */
struct poptOption optionsTable[] = {

   {"title", 't', POPT_ARG_STRING, &field.title, 't'
    "set the 'title' of the album" },
   {"artist", 'a', POPT_ARG_STRING, &field.artist, 'a'
    "set the 'artist' of the album" },
   POPT_AUTOHELP
   POPT_TABLEEND
};

poptContext optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
poptSetOtherOptionHelp(optCon, "[OPTIONS]");

char c;
while ((c = poptGetNextOpt(optCon)) >= 0) {
    switch (c) {
        case 't':
            /* do extra stuff only if you need */
            break;
        case 'a':
            /* do extra stuff only if you need */
            break;
        default:
            poptPrintUsage(optCon, stderr, 0);
            exit(1);
    }
}

if (field.title) printf("\nTitle is [%s]", field.title);
if (field.artist) printf("\nArtist is [%s]", field.artist)

getopt ;) 보다 현명하게 행동하세요.

언급URL : https://stackoverflow.com/questions/7489093/getopt-long-proper-way-to-use-it

반응형