好的,我已经搜索并发现以下两个StackOverflow主题让我朝着正确的方向前进:
注意:所有代码都是PSEUDO-CODE.将在其工作时发布可编译代码.
但是,我仍然对如何在C中使用getopt_long()感到困惑.我正在编写的程序被定义为具有以下可能的标记(但可以包含您绝对需要的数量,其余用空值填充) ):
id3tagEd filename -title "title" -artist "artist" -year 1991 -comment "comment" -album "album" -track 1
Run Code Online (Sandbox Code Playgroud)
现在,根据我的阅读,我需要利用一个结构来获取长期选项,对吗?如果是这样,我写了一些类似的东西:
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}
}
Run Code Online (Sandbox Code Playgroud)
现在,根据我收集的内容,我将通过以下方式调用它:
int option_index = 0;
int values = getopt_long(argc, argv, "tabycu", long_options, &option_index);
Run Code Online (Sandbox Code Playgroud)
从这里开始,我可以严格使用字段结构并在程序中执行我需要的操作吗?但是,如果是这种情况,有人可以解释整个long_options结构吗?我阅读了这些手册页,我只是完全糊涂了.通过重读手册页,我可以看到我可以将变量设置为null,并且应该将所有选项要求设置为"required_argument"?然后通过while()循环设置结构?但是,我看到正在使用optarg.这是由getopt_long()设置的吗?或者是否从示例中遗漏了?
最后一个问题,我将始终有一个未命名的必需选项:filename,我只是使用argv [0]来获取访问权限吗?(因为我可以假设它会是第一个).
在旁注中,这与作业问题有关,但它与修复它无关,它更多的是基础,必须首先通过命令行理解参数传递和解析.
Car*_*rum 29
首先,你可能不希望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}
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以适当地使用它(直接从联机帮助页,我添加了一些注释):
// 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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以根据需要扩展其他字段(并添加一些错误处理,请!).注意 - 如果你想在你的例子中使用-title和-artist喜欢,你需要使用getopt_long_only(),没有短选项.
至于你的filename选择,你可以'?'从getopt_long()电话中得到它,所以你可以在那时处理它.您的其他选择是要求它是第一个或最后一个选项并单独处理它.
小智 7
如果你使用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)
Run Code Online (Sandbox Code Playgroud)
比getopt聪明;)