Простейшая возможная программа getopt, которую я могу получить?

После прочтения по этой ссылке о том, как использовать 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 он останавливается там и никогда не печатает имя файла, который я ввел.

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() с включенными "необязательными аргументами" (ведущий : на строку параметров). Он также распечатывает свои входные данные в конце.

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;

Вот:

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

break выбивает тебя из switch заявление, а не из while петля, так что while цикл продолжается, и вы продолжаете вечно, потому что opt никогда не меняется Вам не хватает логики, здесь вы, вероятно, хотите звонить getopt() опять где-то в петле.

Другие вопросы по тегам