簡體   English   中英

argc / argv中的命令行解析

[英]Command line parsing in argc/argv

我有以下代碼:

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("-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);

您不能在此處釋放cmdLine,因為您的strtok()調用會將cmdLine中的指針分配給argv。 free()在scanOptions()之后,盡管如果直接保存任何optarg指針,它們將指向您具有free()的空間-您使用strdup()可以確保您的情況安全。

重置getopt()

如果以前調用過getopt,則需要重置其一些變量,以便它可以再次掃描(有關說明,請參見getopt聯機幫助頁)。 您需要做:

optind = 0;

argv中的索引錯誤argv中的第一個索引按照慣例是程序名稱,而不是任何程序參數。 因此,請確保您的argv [0]不是您的任何參數。 但是它必須是有效的字符串,而不是NULL指針。

argv [1]應該是第一個參數。

將哨兵添加到argv

main()的傳統argv以NULL指針結尾,您仿真的argv也應該如此。 在while循環之后,執行

argv[argc] = NULL;

getopt(3)認為argv[0]是程序名稱,因此只會解析argv[1]argv[2]等的參數。

要使其工作,請在構建臨時數組時在parse()中將argc初始化為1

int argc = 1;

我無法在您的信息中添加評論。 但我想知道以下內容:

為什么不能直接從Main調用scanOptions()?

scanOptions(argc,argv);

getopt期望參數從索引1開始存儲在argv

約定名稱為argv[0]

因此,您可能希望更改以下代碼:

int argc = 0;

成為:

int argc = 1;

我添加了正確的代碼段以供參考:

    char *param = strtok(cmdLine, " ");
    argv[argc++] = "dummy";
    while (param && argc < MAX_ARGS) {
        argv[argc++] = param;
        param = strtok(NULL, " ");
    }
    scanOptions(argc, argv);
    free(cmdLine);

解決方案是添加argv [argc ++] =“ dummy”; 填充argv [0]並在scanOptions之后調用free(cmdLine)。

這遠非復雜而錯誤的說法。 您無法維持這一點。 使用boost :: program_options代替。

它看起來像:

namespace po = boost::program_options;

boost::program_options::variables_map vars;

po::options_description options("Command line options");

options.add_options()
    ("help", "display this help message and exit")
    ("in", po::value<std::string>()->default_value("file1.txt"), "input file")
    ("out", "output file");

po::store(po::parse_command_line(argc, argv, options), vars);
po::notify(vars);

std::string infile = vars["in"].as<std::string>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM