如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:

prog [-abc] [input [output]]

是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?


相关:

在unicode c++应用程序中解析命令行参数


当前回答

Following from my comment and from rbaleksandar's answer, the arguments passed to any program in C are string values. You are provided the argument count (argc) which gives you the argument indexes zero-based beginning with the name of the program currently being run (which is always argv[0]). That leaves all arguments between 1 - argc as the user supplied arguments for your program. Each will be a string that is contained in the argument vector (which is a pointer to an array of strings you will seen written as char *argv[], or equivalently as a function parameter char **argv) Each of the strings argv[1] to argv[argc-1] are available to you, you simply need to test which argument is which.

这将允许您分离,并使它们可用为命令(cmd),选项(opt)和最后的参数(arg)到您的cmd。

Now it is worth noting, that the rules of your shell (bash, etc..) apply to the arguments passed to your program, word-splitting, pathname and variable expansion apply before your code gets the arguments. So you must consider whether single or more commongly double-quoting will be required around any of your arguments to prevent the normal shell splitting that would otherwise apply (e.g. ls -al my file.txt would results in 4 user-supplied arguments to your code, while ls -al "my file.txt" or ls -al my\ file.txt which would result in the 3 your were expecting.

把所有这些放在一起,您的简短解析可以像下面这样完成。(你也可以自由地做你喜欢的,使用一个开关而不是嵌套的if等…)

#include <stdio.h>

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

    char *cmd = NULL,   /* here, since you are using the arguments  */
         *opt = NULL,   /* themselves, you can simply use a pointer */
         *arg = NULL;   /* or the argument itself without a copy    */

    /* looping using the acutal argument index & vector */
    for (int i = 1; i < argc; i++) {
        if (*argv[i] != '-') {      /* checking if the 1st char is - */
            if (!cmd)               /* cmd is currently NULL, and    */
                cmd = argv[i];      /* no '-' it's going to be cmd   */
            else                    /* otherwise, cmd has value, so  */
                arg = argv[i];       /* the value will be opt        */
        }
        else                /* here the value has a leading '-', so  */
            opt = argv[i];  /* it will be the option */
    }

    printf ("\n cmd : %s\n opt : %s\n arg : %s\n\n",
            cmd, opt, arg);

    return 0;
}

使用/输出示例

如果你运行代码,你会发现它为参数提供了分离,并提供了单独的指针,以方便它们的使用:

$ ./bin/parse_cmd ls -la ./cs3000

 cmd : ls
 opt : -la
 arg : ./cs3000

(需要注意的是,如果你的任务是构建一个命令字符串,你需要复制多个值来表示opt或arg,那么你不能再简单地使用指针,而需要创建存储,要么通过简单的数组声明而不是指针开始,或者你可以根据需要动态分配存储,例如malloc, calloc和/或realloc。然后,您将有可用的存储空间来复制和连接其中的值。)

如果这是你的挑战,那么在所有这些答案之间,你应该知道如何处理你的问题。如果你必须更进一步,实际上让你的程序执行带有opt和arg的cmd,那么你会想要查看fork来生成一个半独立的进程,在其中运行将执行你的cmd opt和arg,使用类似于execv或execvp的东西。祝你好运,如果你有进一步的问题,请发表评论。

其他回答

尝试CLPP库。它是用于命令行参数解析的简单而灵活的库。仅头部和跨平台。仅使用ISO c++和Boost c++库。恕我直言,这比Boost.Program_options简单。

图书馆:http://sourceforge.net/projects/clp-parser

2010年10月26日-新发布2.0rc。修正了许多bug,完整的源代码重构、文档、示例和注释都得到了修正。

还有另一种选择是精益平均c++选项解析器:

http://optionparser.sourceforge.net

它是一个只包含头文件的库(实际上只有一个头文件),与所有其他建议不同 也是独立的,即它没有任何依赖关系。特别是,它不依赖于STL。它甚至不使用异常或任何其他需要库支持的东西。这意味着它可以与普通C语言或其他语言链接,而无需引入“外国”库。

像boost::program_options一样,它的API提供了方便的直接访问选项, 也就是说,你可以这样写代码

如果 (选项[帮助]) ... ;

and

int VERBOSE = options[VERBOSE].count();

然而,与boost::program_options不同的是,这只是使用一个带有(用户提供的)enum索引的数组。这提供了没有权重的关联容器的便利。

它有良好的文档记录,并具有公司友好的许可证(MIT)。

tlmc++ OP包含了一个很好的格式化程序,用于使用可以执行的消息 行换行和列对齐在本地化程序时非常有用,因为它可以确保即使在具有较长消息的语言中输出也会很好。它还省去了手动格式化80列的麻烦。

如果这是linux/unix,那么使用的标准是gnu getopt

http://www.gnu.org/s/libc/manual/html_node/Getopt.html

你的C/ c++程序总是有一个主函数。它是这样的:

    int main(int argc, char**argv) {
        ...
    }

这里argc是一些命令行参数,已经传递给你的程序,argv是一个包含这些参数的字符串数组。因此,命令行参数由调用方进程分隔开(不像在windows中那样是一行)。

现在你需要整理它们:

命令名总是第一个参数(索引0)。 选项只是指定程序应如何工作的特殊参数。按照惯例,它们从-号开始。通常-对于一个字母的选项和-对于任何更长。所以在你的任务中“选项”都是参数,从-开始,而不是第0个。 参数。只是所有其他不是程序名或选项的参数。

我喜欢C的getopt(),但是我老了。: -)