getopt_long() -- 적절한 사용 방법은 무엇입니까?
네, 검색해보니 올바른 방향으로 시작한 StackOverflow 주제가 다음 두 가지 있었습니다.
참고: 모든 코드는 의사 코드입니다. 작동하면 컴파일 가능한 코드가 게시됩니다.
하지만 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
'programing' 카테고리의 다른 글
PHP 객체 리터럴 (0) | 2023.09.15 |
---|---|
기판을 사용하여 Oracle에서 문자열 자르기 (0) | 2023.09.15 |
특정 RUN 명령에 대해 캐시 사용 안 함 (0) | 2023.09.15 |
"iff" 대 "if other if"의 성능 차이 (0) | 2023.09.15 |
React Native에서 Android의 패키지 이름 변경 (0) | 2023.09.15 |