如何在没有getopt的情况下解析c中的命令行参数?

时间:2017-08-28 13:38:03

标签: c arguments getopt

我知道在c中解析命令行参数已经有一些其他的问题和答案,但我希望有人可以告诉我为什么我的代码不起作用。这是我的代码。我想解析我的参数,没有外部头文件,如getopt.h /(unistd.h)或args.h

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

void showUsage(char *prog) {
  printf("Usage for %s...", prog);
}

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

if (argc == 1) {
    showUsage(argv[0]);
    return EXIT_FAILURE;
}
int c;
char *input, *output;

for (c = 0; c < argc; ++c) {
    if (strcmp((char *)argv[c], "-i")) {
        input = (char *)argv[c + 1];
    }
    if (strcmp((char *)argv[c], "-o")) {
        output = (char *)argv[c + 1];
     }
  }
 printf("\nInput %s Output: %s", input, output);
 return EXIT_SUCCESS;
}

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题,但导致您出现问题的主要问题是(正如Weather Vane所指出的那样)您向后返回值为strcmp() - 如果字符串不同则返回true(实际上,它返回一个正数或负数,表示哪个字符串具有较低的第一个字符 - 那个不同;或者如果字符串相同则为零。

此外,您不检查以确保-i或-o参数后面有参数。考虑一下如果将代码调用为progname -i

,代码将执行的操作

此外,在将argv [c + 1]作为文件名后,你不会增加c,所以下次循环你将strcmp()作为一个选项。例如,如果您碰巧将输入文件命名为-o,则会中断。考虑一下你将如何解析progname -i -o -o -i(诚然是一个人为的例子,但你应该能够处理这些事情)。

此外,argv [c]到(char *)的转换是不必要的(它已经是一个char *,而strcmp()无论如何都需要一个char *,所以它本来是自动提升的,即使它没有'曾经)。一般来说,所有那些演员都会隐藏你的错误 - 如果你把它误写为(比如说)调用strcmp(argv, "-i"),那么演员会隐藏你的错误,所以你不得不调试而不是编译器为你举旗。在这种情况下,这很容易找到,但是当你处理更复杂的代码时,可能需要几天时间才能找到。

答案 1 :(得分:0)

以下代码我多年来一直用来解析unix风格的命令行开关。根据需要进行调整:

#include <stdio.h>

int  i, files;
FILE *inf, *outf;

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

  /* process switches; other prms are considered files (2)
     that are opened for input/output. Files not specified
     are taken as stdin and stdout.
  */

  while (++i < argc)
    switch (argv[i][0]) {
      case '-': while (*++argv[i])
                  switch (*argv[i]) {
                  case 'n': case 'N':
                        ++argv[i]; number= 0;
                        while (isdigit(*argv[i]))
                            number = number *10 + *argv[i]++ - '0';
                        argv[i]--;
                        break;

                    case 'P' : printf ("Prm: P\n"); break;
                    case 'O' : printf ("Prm: O\n"); break;
                  default :
                    printf ("Bad switch %c, ignored.\n",*argv[i]);
                  }
                break;

      default :
        switch (files) {
        case 0: if ((inf=fopen(argv[i],"r")) == 0)
                    pexit("Input file %s not found.\n", argv[i]);
                files++; break;
        case 1: if ((outf=fopen(argv[i],"w")) == 0)
                    pexit (" Error creating output file %s.\n", argv[i]);
                files++; break;
        case 2: printf ("Too many file arguments: %s ignored.\n",argv[i]);
                break;
        } /* end switch files */
      } /* end switch argc */

    if (files <1) inf = stdin;
    if (files <2) outf = stdout;
}