我正在传递我的程序输入,我可以在argv中看到它们,但getopt似乎没有我期望的参数。
这就是我运行prog的方式:./ my_prog -X -f filename
<snip>
while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
switch (opt) {
case 'X':
case 'f':
if (optarg == NULL)
fput("no point of living", fp); << for debugging
</snip>
我总是将optarg视为null。为什么?
答案 0 :(得分:9)
你的参数字符串没有:在X之后(例如X:f)所以optarg总是为空。
我还要指出,通常在switch语句中你需要在每个case之后休息一下(通常,并非总是,但通常在解析参数时),所以:
switch ( ... ) {
case 'X': {
// do something
} break;
case 'f': {
// do something else
} break;
}
答案 1 :(得分:1)
还有谁进入此页面:
来自http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html#Using-Getopt:
An option character in this string can be followed by a colon (‘:’) to indicate that it takes a required argument. If an option character is followed by two colons (‘::’), its argument is optional; this is a GNU extension.
所以在你的论证中你可以使用: “X:F:E:E:d:d:”
有同样的问题。
答案 2 :(得分:1)
我刚刚处理了这个问题,看来这个问题从未得到完全回答。
在致电opterr = 0
之前,您必须确保设置外部libc变量getopt
;如果你没有重置它并且getopt
以前在你的系统中任何地方的另一个应用程序中使用它有错误,它将失败参数。我还要重申现有的观点,因为你在case 'X':
之后没有一个中断声明,这是一个问题的确定标志,因为它会落空。
getopt
一次只处理一个参数,因此通过案例X
进入案例f
是件坏事。你应该总是在switch
的每个案例陈述中休息,除非你绝对确定它应该落空(这在我的经验中是非常罕见的)。作为一般的良好实践的另一点,您应该始终在{}(引用您的条件)中包含代码块,除非它是return
语句或break
或导致程序流到的东西退出当前或父块范围或通过函数或方法调用输入新范围。
我认为您的选项字符串Xf:eE:dD很好。这表明:
1)以下只是始终具有空参数的选项标志:XedD
2)以下选项需要一个参数:fE
如果这是您正在寻找的功能,那么给定的选项字符串就可以了。如果你正在使用GNU libc,根据上面的其他答案,你可以在选项字符串中的一个选项之后使用::来表示该选项可能有一个参数,但不是必须的。
因此,在文件的顶部,请确保您至少拥有:
extern int opterr;
然后在您的代码中第一次致电getopt
之前,请将opterr
设置为0。
e.g。
opterr = 0;
while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
switch (opt) {
case 'X':
case 'f':
if (optarg == NULL)
fput("no point of living", fp); << for debugging
这应至少部分解决您的问题。这是一个示例的链接:
http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
干杯,
乔恩
答案 3 :(得分:0)
我知道这是旧的,但我最近注意到我多年前使用 getopt 的方式发生了变化。也许这是一个不同的环境,但我发现今天使用它需要 optarg 直接在标志之后(无空格),否则 optarg 为空。
使用您的示例,将 ./my_prog -X -f filename
替换为 ./my_prog -X -ffilename
我发现即使感觉不对也很好用。希望这可以帮助其他人以后。请务必同时尝试两种方式。