2013-09-01 2 views
1

Прочитав это link о том, как использовать 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 

Я могу» t, похоже, понимает, когда я запускаю его с помощью опции -v, он никогда не останавливает печать версии и с -f filename он останавливается и никогда не печатает имя файла, которое я ввел.

+0

Это даже компилируется? Что такое '' vf ''в сигнатуре' main'? –

+0

Предполагая, что вы прочитали весь текст в моем вопросе, да, он компилируется, иначе я не стал бы спрашивать о проблемах, возникающих при запуске программы. v и f - доступные варианты (-v и -f). Значение: после f означает, что -f хочет получить еще один параметр от пользователя. – yaku

+0

Ну, так как вы опубликовали * не * компилировали, я думаю, что мой вопрос был разумным. –

ответ

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

+0

Да, это работает. Спасибо – yaku

+0

Спасибо Джонатан, ваши примеры действительно просветительские. – yaku

+0

@yaku add printf ("Имя файла было% s \ n", filename); в случае «f» и удалять после. потому что если вы используете опцию v, то также будет печатать имя файла как неуказанное. – Gangadhar

1

Здесь:

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

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

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; 
+0

да, извините, что я плохо вклеил свой код, пожалуйста, проверьте еще раз. – yaku

Смежные вопросы