getopt 值保持为空
我正在传递程序输入,我可以在 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。为什么?
I am passing my program inputs and I could see them in argv but getopt doesnt seem to have the argument that I expect.
This is how I run my 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>
I always get optarg as null. WHY?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的参数字符串在 X 之后没有 : (例如 X:f),因此 optarg 将始终为 null。
我还要指出,通常在 switch 语句中,您需要在每种情况之后休息(通常,并非总是如此,但通常在解析参数时),因此:
Your argument string does not have a : after the X (e.g. X:f) so optarg will always be null.
I'll also point out that generally in a switch statement you'll want a break after each case (generally, not always, but when parsing arguments usually), so:
我刚刚处理了这个问题,看来这个问题从未得到完全解答。
在调用
getopt
之前,您必须确保设置外部 libc 变量opterr = 0
;如果您不重置它,并且getopt
之前在使用它的系统中任何地方的另一个应用程序中出现错误,则该参数将会失败。我还将重申现有的一点,因为在case 'X':
之后没有break语句,这是一个问题的明确迹象,因为它会失败。getopt
一次仅处理一个参数,因此从 caseX
变为 casef
是一件坏事。您应该始终在switch
的每个 case 语句中都有一个中断,除非您完全确定它应该失败(这在我的经验中非常罕见)。作为一般良好实践的另一点,您应该始终将代码块括在 { } 中(指您的条件),除非它是return
语句或break
或导致程序流向退出当前或父块作用域,或者通过函数或方法调用进入新作用域。我认为你的选项字符串 Xf:eE:dD 很好。这表明:
1) 以下只是始终具有空参数的选项标志: XedD
2) 以下选项需要参数: fE
如果这是您正在寻找的功能,则给定的选项字符串就可以了。如果您使用的是 GNU libc,根据上面的其他答案,您可以在选项字符串中的选项后面使用 :: 来指示该选项可能有参数,但不是必须的。
因此,在文件顶部,请确保至少具有:
然后在代码中第一次调用
getopt
之前,将opterr
设置为 0。例如,
这应该至少部分解决您的问题。以下是示例的链接:
http://www. gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
干杯,
乔恩
I just dealt with this issue, and it appears this question was never fully answered.
You have to make sure you're setting the external libc variable
opterr = 0
before you callgetopt
; if you don't reset it andgetopt
previously had an error in another application anywhere in your system that used it, it will fail for the argument. I'll also reiterate the existing point that because you don't have a break statement aftercase 'X':
that's a sure sign of an issue since it will fall through.getopt
only processes one argument at a time, so falling through caseX
into casef
is a bad thing to do. You should always have a break in each case statement of aswitch
unless you are absolutely certain it should fall through (which is very rare in my experience). As another bit of general good practice, you should always enclose blocks of code in { } (referring to your conditional) unless it's areturn
statement orbreak
or something that causes the program flow to to drop out of the current or parent block scope or to enter a new scope through a function or method call.I think your option string Xf:eE:dD is fine. This indicates that:
1) The following will simply be option flags that always have a null argument: XedD
2) The following options will require an argument: fE
If this is the functionality you're looking for, the given option string is fine. If you're using GNU libc, per the other above answer, you can use :: after an option in the option string to indicate that the option might have an argument, but doesn't have to.
So at the top of your file make sure you at least have:
Then right before you call
getopt
for the first time in your code, setopterr
to 0.e.g.
This should at least partially resolve your issue. Here's a link to an example:
http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
Cheers,
Jon
对于其他人,请访问此页面:
来自 http://www.gnu.org/ software/libc/manual/html_node/Using-Getopt.html#Using-Getopt:
该字符串中的选项字符后面可以跟一个冒号(':'),以指示它需要一个必需的参数。如果选项字符后跟两个冒号('::'),则其参数是可选的;这是一个 GNU 扩展。
所以在你的论点中你可以使用:
“X:f:e:E:d:D:”
有同样的问题。
For who else get to this page:
From 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.
so in your argument you might use:
"X:f:e:E:d:D:"
Had the same problem.
我知道这已经很旧了,但我最近注意到几年前使用 getopt 的方式发生了变化。也许这是一个不同的环境,但我发现今天使用它需要 optarg 直接位于标志之后(无空格),否则 optarg 为空。
使用您的示例,将
./my_prog -X -f filename
替换为./my_prog -X -ffilename
我发现即使感觉不对,效果也很好。希望这可以帮助其他人以后。确保两种方法都尝试一下。
I know this is old but I recently noticed changed behaviour in the way I used to use getopt years ago. Maybe it was a different environment but I find using it today requires the optarg to be DIRECTLY after the flag (no space) otherwise optarg is null.
Using your example, replace
./my_prog -X -f filename
with./my_prog -X -ffilename
I find that works fine even though it feels wrong. Hope this helps someone else out later. Make sure to try it both ways.