getopt 值保持为空

发布于 2024-11-17 04:08:55 字数 417 浏览 2 评论 0原文

我正在传递程序输入,我可以在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

十年不长 2024-11-24 04:08:55

您的参数字符串在 X 之后没有 : (例如 X:f),因此 optarg 将始终为 null。

我还要指出,通常在 switch 语句中,您需要在每种情况之后休息(通常,并非总是如此,但通常在解析参数时),因此:

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

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

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;
}
瑕疵 2024-11-24 04:08:55

我刚刚处理了这个问题,看来这个问题从未得到完全解答。

在调用 getopt 之前,您必须确保设置外部 libc 变量 opterr = 0;如果您不重置它,并且 getopt 之前在使用它的系统中任何地方的另一个应用程序中出现错误,则该参数将会失败。我还将重申现有的一点,因为在 case 'X': 之后没有break语句,这是一个问题的明确迹象,因为它会失败。

getopt 一次仅处理一个参数,因此从 case X 变为 case f 是一件坏事。您应该始终在 switch 的每个 case 语句中都有一个中断,除非您完全确定它应该失败(这在我的经验中非常罕见)。作为一般良好实践的另一点,您应该始终将代码块括在 { } 中(指您的条件),除非它是 return 语句或 break 或导致程序流向退出当前或父块作用域,或者通过函数或方法调用进入新作用域。

我认为你的选项字符串 Xf:eE:dD 很好。这表明:

1) 以下只是始终具有空参数的选项标志: XedD

2) 以下选项需要参数: fE

如果这是您正在寻找的功能,则给定的选项字符串就可以了。如果您使用的是 GNU libc,根据上面的其他答案,您可以在选项字符串中的选项后面使用 :: 来指示该选项可能有参数,但不是必须的。

因此,在文件顶部,请确保至少具有:

extern int opterr;

然后在代码中第一次调用 getopt 之前,将 opterr 设置为 0。

例如,

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

干杯,

乔恩

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

总攻大人 2024-11-24 04:08:55

对于其他人,请访问此页面:
来自 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.

为你拒绝所有暧昧 2024-11-24 04:08:55

我知道这已经很旧了,但我最近注意到几年前使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文