1

の使用方法に関するこのリンクgetopt()を読んだ後、小さな例を取得しようとしています。

私が欲しいのは、次のようなものです:

./prog -v      # show me prog version
./prog -f filename  # just show me the filename I entered from the command line

これまでに書いたものは次のとおりです。

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

int
main(int argc, *argv[]) {
     char VER[] = "0.1.1";
     int opt;
     opt = getopt(argc, argv, "vf:");
     char *filename;

      while (opt != -1) {
           switch(opt) {
            case 'v':
                printf("version is %s", VER);
                break;
            case 'f':
                filename = optarg;
                break;
            }
     }
    printf("The filename was %s", filename);
    return 0;
}

コードを次のようにコンパイルします。

$ gcc prog.c -o prog -Wall -Wextra

-vオプションを指定して実行すると、バージョンの印刷が停止され-f filenameず、そこで停止し、入力したファイル名が印刷されないことを理解できないようです。

4

3 に答える 3

3

一度しか呼べないから止まらないgetopt()。可能な修正:

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

int
main(int argc, char **argv)
{
    char VER[] = "0.1.1";
    int opt;
    const char *filename = "unspecified";

    while ((opt = getopt(argc, argv, "vf:")) != -1)
    {
        switch (opt)
        {
            case 'v':
                printf("version is %s\n", VER);
                break;
            case 'f':
                filename = optarg;
                break;
            default:
                fprintf(stderr, "Usage: %s [-v][-f file]\n", argv[0]);
                return(1);
        }
    }
    printf("The filename was %s\n", filename);
    return 0;
}

filenameが初期化されていること、printf()出力が改行で終わっていること、エラー ケースが報告されていることを確認したことに注意してください。

これは、もう少し複雑な別のサンプル プログラムです。

/* Example 1 - using POSIX standard getopt() */

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

int
main(int argc, char **argv)
{
    int opt;
    int i;
    int bflag = 0;
    int aflag = 0;
    int errflag = 0;
    char *ifile = 0;
    char *ofile = 0;

    while ((opt = getopt(argc, argv, ":abf:o:")) != -1)
    {
        switch (opt)
        {
        case 'a':
            if (bflag)
                errflag++;
            else
                aflag++;
            break;
        case 'b':
            if (aflag)
                errflag++;
            else
                bflag++;
            break;
        case 'f':
            ifile = optarg;
            break;
        case 'o':
            ofile = optarg;
            break;
        case ':':   /* -f or -o without operand */
            fprintf(stderr, "Option -%c requires an operand\n", optopt);
            errflag++;
            break;
        case '?':
        default:
            fprintf(stderr, "Unrecognized option: -%c\n", optopt);
            errflag++;
            break;
        }
    }

    if (errflag)
    {
        fprintf(stderr, "Usage: %s [-a|-b][-f in][-o out] [file ...]\n", argv[0]);
        exit(2);
    }

    printf("Flags: a = %d, b = %d\n", aflag, bflag);
    if (ifile != 0)
        printf("Input: %s\n", ifile);
    if (ofile != 0)
        printf("Output: %s\n", ofile);
    printf("Argc = %d, OptInd = %d\n", argc, optind);
    for (i = optind; i < argc; i++)
        printf("File: %s\n", argv[i]);
    return(EXIT_SUCCESS);
}

これは、Sun のマニュアルの例に基づいています。とオプションは相互に排他的です-a。これは、「オプションの引数」が有効になっている (オプション文字列の先頭-b) POSIX (の制限) を示しています。また、最後に入力を出力します。getopt():

于 2013-09-01T03:18:11.977 に答える
1

ここ:

case 'v':
    printf("version is %s", VER);
    break;

これbreakは、ループからではなく、switchステートメントから抜け出しているwhileため、ループが継続し、決して変更whileされないため、永遠に続きます。optいくつかのロジックが欠落しています。ここでは、おそらくgetopt()ループのどこかで再度呼び出したいと考えています。

于 2013-09-01T03:12:47.937 に答える
1
int main(int argc, *argv[], "vf")   


getopt.c:5:20: error: expected declaration specifiers or â...â before â*â token
getopt.c:5:28: error: expected declaration specifiers or â...â before string constant

これはあるべきです

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

変更されたコード:

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

int main(int argc, char *argv[])
  {
     char VER[] = "0.1.1";
     int opt;
   opt = getopt(argc, argv, "vf:");
     char *filename;

      while (opt != -1) {
           switch(opt) {
            case 'v':
                printf("version is %s\n", VER);
                exit(0);
            case 'f':
             //   filename = optarg;
                 printf("The filename was %s\n", argv[2]);
                exit(0);


            }
     }
    return 0;
于 2013-09-01T03:13:36.957 に答える