我有以下代码:

void parse(char *commandLine) {
    int rc = 0;
    int argc = 0;
    char *cmdLine;
    char *argv[MAX_ARGS];
    filename = NULL;
    stdoutFilename = NULL;
    stderrFilename = NULL;
    cmdLine = strdup(commandLine);
    char *param = strtok(cmdLine, " ");
    while (param && argc < MAX_ARGS) {
        argv[argc++] = param;
        param = strtok(NULL, " ");
        printf("%s\n", argv[argc-1]);
    }
    free(cmdLine);
    scanOptions(argc, argv);
    printf("Filename %s\n", filename);

...

void scanOptions(int argc, char *argv[]) {
    int c ;
    while ((c = getopt (argc, argv, "Df:e:o:")) != -1) {
        switch (c) {
            case 'D': __debug = 1; break;
            case 'f': filename = strdup(optarg); break;
            case 'o': stdoutFilename = strdup(optarg); break;
            case 'e': stderrFilename = strdup(optarg); break;
            default: fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
        }
    }
}

filename、stdoutFilenamestderrFilename是全局变量。
如果我将parse方法调用为:
parse("-ftest/testfile.txt") the variable filename is not set and the call to
printf("Filename %s\n", filename); prints "Filename (null)".

怎么了?

最佳答案

有一些事情是错误的,可能是也可能不是你问题的原因:
使用释放的内存

free(cmdLine);
scanOptions(argc, argv);

无法在此处释放命令行,因为strtok()调用将在命令行内将指针分配给argv。在scanpoptions()之后free()它,但是如果直接保存任何optarget指针,它们将指向有free()的空间-您可以使用strdup()这样您就安全了。
正在重置getopt()
如果以前调用过getopt,则需要重置它的一些变量,以便它可以再次扫描(有关解释,请参阅getopt手册页)。你需要做的是:
optind = 0;

argv中的索引错误
argv中的第一个索引按照约定是程序名,而不是任何程序参数。
因此,确保argv[0]不是您的任何参数。但它必须是有效的字符串,而不是空指针。
argv[1]应该是第一个参数。
在argv中添加哨兵
main()的传统argv以空指针结束,模拟的argv也应该以空指针结束。
在while循环之后,do
argv[argc] = NULL;

关于c - argc/argv中的命令行解析,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16687258/

10-11 22:20
查看更多