3

パースペクティブを理解するために getopt を使用して簡単なコードを作成しました。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[])
{

 /* Here since c is followed with colon, so 'c' takes an argument */
  const char *optstring = "abc:d";

  int ret;

  while((ret=getopt(argc, argv, optstring))!= -1)
  {
    switch(ret)
    {
      case 'a':
        printf("Option found: a, optind = %d\n",optind);
        break;

      case 'b':
         printf("Option found: b, optind = %d\n",optind);
         break;

      case 'c':
         printf("Option found: c, optind = %d\n",optind);
         printf("Option argument: %s\n",optarg);
         break;

      case 'd':
         printf("Option found: d, optind = %d\n",optind);
         break;

      case ':':
         printf("The option takes an argument which is missing");
         break;

     //case '?':
       //   printf("Didn't you enter an invalid option?");
           // break;
     }
   }
 }

問題は:

(1) ケース 1:case '?'がコメント化さ れている場合:

[root@dhcppc0 getopt]# ./a.out -a -b -c
    Option found: a, optind = 2
    Option found: b, optind = 3
    ./a.out: option requires an argument -- c

したがって、ご覧case ':'のとおり、引数が欠落していると getopt によって ':' (コロン) が返されることが通常想定されるため、 は有効になりませんでした。

(2) ケース 2: そして、コメントを外してプログラムを実行すると、case '?引数が欠落している場合でもヒットします。

enter code here
[root@dhcppc0 getopt]# ./a.out -a -b -c
   Option found: a, optind = 2
   Option found: b, optind = 3
      ./a.out: option requires an argument -- c
      Didn't you enter an invalid option?

ここで私が見逃している点は何ですか?

後で追加:

また./a.out: option requires an argument -- c、デフォルトのエラーが発生するのはなぜですか? 私はすでに でそれを処理していてcase ':'、デフォルトのエラー メッセージが必要ないので、どのように処理するのですか?

再度追加:答えで示唆されているように、 optstring - の先頭にコロンを使用しましたがconst char *optstring = ":abc:d"、なぜこれが起こっているのですか?

./a.out -a -b -c -d returns -d as the argument to c?? -d is a separate optional character and not any argument
4

2 に答える 2

4

man getoptから:

getopt() は、optstring に含まれていないオプション文字を argv で見つけた場合、または欠落しているオプション引数を検出した場合、'?' を返します。そして、外部変数 optopt を実際のオプション文字に設定します。

したがって、プログラムの動作は設計によるものです。getopt の期待される戻り値と、man ページの次のステートメントを混同している可能性があります。

optstring の最初の文字 (上記のオプションの '+' または '-' に続く) がコロン (':') の場合、getopt() は '?' ではなく ':' を返します。オプションの引数が欠落していることを示します。エラーが検出され、optstring の最初の文字がコロンではなく、外部変数 opterr がゼロ以外 (デフォルト) の場合、getopt() はエラー メッセージを出力します。

したがって、optstring を次のように宣言してみてください。

const char *optstring = ":abc:d";
于 2012-02-25T06:42:49.583 に答える
4

関数の POSIX バージョンは次のようにgetopt()指定します。

getopt()に含まれていないオプション文字に遭遇した場合、 ( '?' ) 文字optstringを返します。<question-mark>オプション引数の欠落を検出すると<colon>、 optstring の最初の文字が の場合は文字 ( ':' )を返し、そうでない場合<colon><question-mark>文字 ( '?' ) を返します。

yourは a でoptstr始まらないため、代わりに:a を返す必要があり?ます。

于 2012-02-25T06:44:58.680 に答える