开发者

getopt value stays null

I a开发者_StackOverflowm 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?


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:

switch ( ... ) {
    case 'X': {
        // do something
    } break;

    case 'f': {
        // do something else
    } break;
}


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.


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 call getopt; if you don't reset it and getopt 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 after case '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 case X into case f is a bad thing to do. You should always have a break in each case statement of a switch 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 a return statement or break 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:

extern int opterr;

Then right before you call getopt for the first time in your code, set opterr to 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

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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜