简体   繁体   English

argc / argv中的命令行解析

[英]Command line parsing in argc/argv

I have the following code: 我有以下代码:

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

... ...

and

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, stdoutFilename and stderrFilename are global variables. filename, stdoutFilenamestderrFilename全局变量。 If I call the parse method as: 如果我将解析方法称为:

parse("-ftest/testfile.txt") the variable filename is not set and the call to 
printf("Filename %s\n", filename); prints "Filename (null)".

What's wrong with that? 怎么了

There's a few things wrong, that may or may not be the cause of your problem: 有一些错误,这可能是也可能不是您的问题的原因:

Use of freed memory 使用释放的内存

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

You can't free the cmdLine here, since your strtok() calls will assign pointers inside cmdLine to your argv. 您不能在此处释放cmdLine,因为您的strtok()调用会将cmdLine中的指针分配给argv。 free() it after scanOptions() , though if you save any optarg pointers directly, they will point into space that you have free()'d - you use strdup() so youre safe in your case. free()在scanOptions()之后,尽管如果直接保存任何optarg指针,它们将指向您具有free()的空间-您使用strdup()可以确保您的情况安全。

Resetting getopt() 重置getopt()

If you have called getopt previously, you need to reset some of its variables so it can scan again, (see the getopt manpage for an explanation). 如果以前调用过getopt,则需要重置其一些变量,以便它可以再次扫描(有关说明,请参见getopt联机帮助页)。 You need to do: 您需要做:

optind = 0;

Wrong index in argv The first index in argv is by convention the program name, not any program arguments. argv中的索引错误argv中的第一个索引按照惯例是程序名称,而不是任何程序参数。 So make sure your argv[0] isn't any of your arguments. 因此,请确保您的argv [0]不是您的任何参数。 But it needs to be a valid string and not eg a NULL pointer. 但是它必须是有效的字符串,而不是NULL指针。

argv[1] should be the first argument. argv [1]应该是第一个参数。

Add a sentiel to argv 将哨兵添加到argv

The traditional argv of main() ends with a NULL pointer, your emulated argv should too. main()的传统argv以NULL指针结尾,您仿真的argv也应该如此。 After the while loop, do 在while循环之后,执行

argv[argc] = NULL;

getopt(3) considers argv[0] to be the program name and so will only parse arguments for argv[1] , argv[2] , etc... getopt(3)认为argv[0]是程序名称,因此只会解析argv[1]argv[2]等的参数。

To make it work, init argc to 1 in parse() while you build your temporary array: 要使其工作,请在构建临时数组时在parse()中将argc初始化为1

int argc = 1;

I cannot add comments to your post. 我无法在您的信息中添加评论。 But i would like to know the following:- 但我想知道以下内容:

why cant you call scanOptions() directly from Main. 为什么不能直接从Main调用scanOptions()?

scanOptions(argc, argv); scanOptions(argc,argv);

getopt expects the parameters to be stored in argv from index 1 on. getopt期望参数从索引1开始存储在argv

argv[0] by conventions is used by the program's name. 约定名称为argv[0]

So you might like to change your code from: 因此,您可能希望更改以下代码:

int argc = 0;

to be: 成为:

int argc = 1;

I add the correct piece of code for reference: 我添加了正确的代码段以供参考:

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

The solution is to add argv[argc++] = "dummy"; 解决方案是添加argv [argc ++] =“ dummy”; to fill argv[0] and to call free(cmdLine) after scanOptions. 填充argv [0]并在scanOptions之后调用free(cmdLine)。

This is far to complicated and error phrone. 这远非复杂而错误的说法。 You cannot maintain this. 您无法维持这一点。 Use boost::program_options instead. 使用boost :: program_options代替。

It will look like: 它看起来像:

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.

相关问题 在C中使用argv和argc解析命令行 - Parsing command line using argv and argc in C 命令行 arguments argv 和 argc - command line arguments argv and argc Argc返回1,argv返回NULL,尽管输入了命令行参数 - Argc returning as 1, argv returning NULL, despite putting in command line arguments 使用命令行参数 (argc, argv) 的 C 计算器程序 - Calculator program in C using Command Line Arguments (argc, argv) C程序:命令行使用argv,argc,读入链表 - C Program: Command Line using argv, argc, reading into linked list 解析 c 中的 argc 和 argv[] 参数 - Parsing argc and argv[] parameter in c 将命令行字符串解析为argv格式 - Parsing command line string in to argv format main(int argc,char * argv [])给*作为命令行参数给出奇怪的结果 - main(int argc, char *argv[]) giving strange results for * as command line argument argv、envp、argc(命令行参数)的最大汇总大小总是远离 ARG_MAX 限制 - The maximum summarized size of argv, envp, argc (command line arguments) is always far from the ARG_MAX limit 定义了unicode的int _tmain(int argc,TCHAR * argv [])无法识别的命令行争论 - command line arguements not recognised by int _tmain ( int argc, TCHAR* argv[] ) with unicode defined
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM