我知道在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;
}
答案 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;
}