在C中是否有办法解析一段文本并获取argv和argc的值,就像文本已经在命令行中传递给应用程序一样?
这不一定适用于Windows,只需要Linux - 我也不关心引用参数。
答案 0 :(得分:28)
我很惊讶没有人使用标准POSIX功能提供最简单的答案:
http://www.opengroup.org/onlinepubs/9699919799/functions/wordexp.html
答案 1 :(得分:15)
这是我的贡献。它很好而且很短,但需要注意的是:
代码:
enum { kMaxArgs = 64 };
int argc = 0;
char *argv[kMaxArgs];
char *p2 = strtok(commandLine, " ");
while (p2 && argc < kMaxArgs-1)
{
argv[argc++] = p2;
p2 = strtok(0, " ");
}
argv[argc] = 0;
您现在可以使用argc和argv,或者将它们传递给声明为“foo(int argc,char ** argv)”的其他函数。
答案 2 :(得分:11)
如果glib解决方案对你的情况来说太过分了,你可以考虑自己编写一个。
然后你可以:
下图应澄清(希望):
aa bbb ccc "dd d" ee <- original string
aa0bbb0ccc00dd d00ee0 <- transformed string
| | | | |
argv[0] __/ / / / /
argv[1] ____/ / / /
argv[2] _______/ / /
argv[3] ___________/ /
argv[4] ________________/
可能的API可能是:
char **parseargs(char *arguments, int *argc);
void freeparsedargs(char **argv);
您需要额外考虑安全地实现freeparsedargs()。
如果您的字符串非常长并且您不想扫描两次,您可以考虑使用替代方法,例如为argv数组分配更多元素(并在需要时重新分配)。
编辑:建议的解决方案(不处理引用的参数)。
#include <stdio.h>
static int setargs(char *args, char **argv)
{
int count = 0;
while (isspace(*args)) ++args;
while (*args) {
if (argv) argv[count] = args;
while (*args && !isspace(*args)) ++args;
if (argv && *args) *args++ = '\0';
while (isspace(*args)) ++args;
count++;
}
return count;
}
char **parsedargs(char *args, int *argc)
{
char **argv = NULL;
int argn = 0;
if (args && *args
&& (args = strdup(args))
&& (argn = setargs(args,NULL))
&& (argv = malloc((argn+1) * sizeof(char *)))) {
*argv++ = args;
argn = setargs(args,argv);
}
if (args && !argv) free(args);
*argc = argn;
return argv;
}
void freeparsedargs(char **argv)
{
if (argv) {
free(argv[-1]);
free(argv-1);
}
}
int main(int argc, char *argv[])
{
int i;
char **av;
int ac;
char *as = NULL;
if (argc > 1) as = argv[1];
av = parsedargs(as,&ac);
printf("== %d\n",ac);
for (i = 0; i < ac; i++)
printf("[%s]\n",av[i]);
freeparsedargs(av);
exit(0);
}
答案 3 :(得分:9)
始终精彩的glib有g_shell_parse_args()
,听起来就像你所追求的那样。
如果你对引用甚至不感兴趣,这可能有点矫枉过正。您需要做的就是使用空格作为标记字符进行标记。写一个简单的例程来做到这一点不应该花很长时间,真的。
如果你对记忆并不吝啬,那么在没有重新分配的情况下一次性完成它应该很容易;假设每个第二个字符都是空格的最坏情况,因此假设一串n
个字符包含最多(n + 1) / 2
个参数,并且(当然)最多n
个字节的参数文本(不包括终结者)。
答案 4 :(得分:6)
这是Windows和Unix的解决方案(在Linux,OSX和Windows上测试)。使用Valgrind和Dr. Memory进行了测试。
它对POSIX系统使用wordexp,对Windows使用CommandLineToArgvW。
请注意,对于Windows解决方案,大多数代码都使用漂亮的Win32 API在char **
和wchar_t **
之间进行转换,因为没有CommandLineToArgvA
可用(ANSI版本)。
#ifdef _WIN32
#include <windows.h>
#else
#include <wordexp.h>
#endif
char **split_commandline(const char *cmdline, int *argc)
{
int i;
char **argv = NULL;
assert(argc);
if (!cmdline)
{
return NULL;
}
// Posix.
#ifndef _WIN32
{
wordexp_t p;
// Note! This expands shell variables.
if (wordexp(cmdline, &p, 0))
{
return NULL;
}
*argc = p.we_wordc;
if (!(argv = calloc(*argc, sizeof(char *))))
{
goto fail;
}
for (i = 0; i < p.we_wordc; i++)
{
if (!(argv[i] = strdup(p.we_wordv[i])))
{
goto fail;
}
}
wordfree(&p);
return argv;
fail:
wordfree(&p);
}
#else // WIN32
{
wchar_t **wargs = NULL;
size_t needed = 0;
wchar_t *cmdlinew = NULL;
size_t len = strlen(cmdline) + 1;
if (!(cmdlinew = calloc(len, sizeof(wchar_t))))
goto fail;
if (!MultiByteToWideChar(CP_ACP, 0, cmdline, -1, cmdlinew, len))
goto fail;
if (!(wargs = CommandLineToArgvW(cmdlinew, argc)))
goto fail;
if (!(argv = calloc(*argc, sizeof(char *))))
goto fail;
// Convert from wchar_t * to ANSI char *
for (i = 0; i < *argc; i++)
{
// Get the size needed for the target buffer.
// CP_ACP = Ansi Codepage.
needed = WideCharToMultiByte(CP_ACP, 0, wargs[i], -1,
NULL, 0, NULL, NULL);
if (!(argv[i] = malloc(needed)))
goto fail;
// Do the conversion.
needed = WideCharToMultiByte(CP_ACP, 0, wargs[i], -1,
argv[i], needed, NULL, NULL);
}
if (wargs) LocalFree(wargs);
if (cmdlinew) free(cmdlinew);
return argv;
fail:
if (wargs) LocalFree(wargs);
if (cmdlinew) free(cmdlinew);
}
#endif // WIN32
if (argv)
{
for (i = 0; i < *argc; i++)
{
if (argv[i])
{
free(argv[i]);
}
}
free(argv);
}
return NULL;
}
答案 5 :(得分:3)
我刚刚为普通C中的嵌入式项目做了这个,我有一个CLI来解析串口输入并使用参数执行一组有限的命令。
这可能不是最好的,但是尽可能小而高效:
int makeargs(char *args, int *argc, char ***aa) {
char *buf = strdup(args);
int c = 1;
char *delim;
char **argv = calloc(c, sizeof (char *));
argv[0] = buf;
while (delim = strchr(argv[c - 1], ' ')) {
argv = realloc(argv, (c + 1) * sizeof (char *));
argv[c] = delim + 1;
*delim = 0x00;
c++;
}
*argc = c;
*aa = argv;
return c;
}
进行测试:
int main(void) {
char **myargs;
int argc;
int numargs = makeargs("Hello world, this is a test", &argc, &myargs);
while (numargs) {
printf("%s\r\n", myargs[argc - numargs--]);
};
return (EXIT_SUCCESS);
}
答案 6 :(得分:2)
Matt Peitrek的LIBTINYC有一个名为argcargv.cpp的模块,它接受一个字符串并将其解析到带有引用参数的参数数组中。请注意,它是特定于Windows的,但它非常简单,因此应该很容易移动到您想要的任何平台。
答案 7 :(得分:2)
我最后写了一个函数来自己做这个,我觉得它不是很好,但它适用于我的目的 - 随意建议改进其他需要这个的人:
void parseCommandLine(char* cmdLineTxt, char*** argv, int* argc){
int count = 1;
char *cmdLineCopy = strdupa(cmdLineTxt);
char* match = strtok(cmdLineCopy, " ");
// First, count the number of arguments
while(match != NULL){
count++;
match = strtok(NULL, " ");
}
*argv = malloc(sizeof(char*) * (count+1));
(*argv)[count] = 0;
**argv = strdup("test"); // The program name would normally go in here
if (count > 1){
int i=1;
cmdLineCopy = strdupa(cmdLineTxt);
match = strtok(cmdLineCopy, " ");
do{
(*argv)[i++] = strdup(match);
match = strtok(NULL, " ");
} while(match != NULL);
}
*argc = count;
}
答案 8 :(得分:1)
#include <cctype> // <ctype.h> for isspace()
/**
* Parse out the next non-space word from a string.
* @note No nullptr protection
* @param str [IN] Pointer to pointer to the string. Nested pointer to string will be changed.
* @param word [OUT] Pointer to pointer of next word. To be filled.
* @return pointer to string - current cursor. Check it for '\0' to stop calling this function
*/
static char* splitArgv(char **str, char **word)
{
constexpr char QUOTE = '\'';
bool inquotes = false;
// optimization
if( **str == 0 )
return NULL;
// Skip leading spaces.
while (**str && isspace(**str))
(*str)++;
if( **str == '\0')
return NULL;
// Phrase in quotes is one arg
if( **str == QUOTE ){
(*str)++;
inquotes = true;
}
// Set phrase begining
*word = *str;
// Skip all chars if in quotes
if( inquotes ){
while( **str && **str!=QUOTE )
(*str)++;
//if( **str!= QUOTE )
}else{
// Skip non-space characters.
while( **str && !isspace(**str) )
(*str)++;
}
// Null terminate the phrase and set `str` pointer to next symbol
if(**str)
*(*str)++ = '\0';
return *str;
}
/// To support standart convetion last `argv[argc]` will be set to `NULL`
///\param[IN] str : Input string. Will be changed - splitted to substrings
///\param[IN] argc_MAX : Maximum a rgc, in other words size of input array \p argv
///\param[OUT] argc : Number of arguments to be filled
///\param[OUT] argv : Array of c-string pointers to be filled. All of these strings are substrings of \p str
///\return Pointer to the rest of string. Check if for '\0' and know if there is still something to parse. \
/// If result !='\0' then \p argc_MAX is too small to parse all.
char* parseStrToArgcArgvInsitu( char *str, const int argc_MAX, int *argc, char* argv[] )
{
*argc = 0;
while( *argc<argc_MAX-1 && splitArgv(&str, &argv[*argc]) ){
++(*argc);
if( *str == '\0' )
break;
}
argv[*argc] = nullptr;
return str;
};
#include <iostream>
using namespace std;
void parseAndPrintOneString(char *input)
{
constexpr size_t argc_MAX = 5;
char* v[argc_MAX] = {0};
int c=0;
char* rest = parseStrToArgcArgvInsitu(input,argc_MAX,&c,v);
if( *rest!='\0' ) // or more clear `strlen(rest)==0` but not efficient
cout<<"There is still something to parse. argc_MAX is too small."<<endl;
cout << "argc : "<< c << endl;
for( int i=0; i<c; i++ )
cout<<"argv["<<i<<"] : "<<v[i] <<endl;
/*//or condition is `v[i]`
for( int i=0; v[i]; i++ )
cout<<"argv["<<i<<"] : "<<v[i] <<endl;*/
}
int main(int argc, char* argv[])
{
char inputs[][500] ={
"Just another TEST\r\n"
, " Hello my world 'in quotes' \t !"
, "./hi 'Less is more'"
, "Very long line with \"double quotes\" should be parsed several times if argv[] buffer is small"
, " \t\f \r\n"
};
for( int i=0; i<5; ++i ){
cout<<"Parsing line \""<<inputs[i]<<"\":"<<endl;
parseAndPrintOneString(inputs[i]);
cout<<endl;
}
}
Parsing line "Just another TEST\r\n":
argc : 3
argv[0] : Just
argv[1] : another
argv[2] : TEST
Parsing line " Hello my world 'in quotes' !":
There is still something to parse. argc_MAX is too small.
argc : 4
argv[0] : Hello
argv[1] : my
argv[2] : world
argv[3] : in quotes
Parsing line "./hi 'Less is more'":
argc : 2
argv[0] : ./hi
argv[1] : Less is more
Parsing line "Very long line with "double quotes" should be parsed several times if argv[] buffer is small":
There is still something to parse. argc_MAX is too small.
argc : 4
argv[0] : Very
argv[1] : long
argv[2] : line
argv[3] : with
Parsing line "
":
argc : 0
答案 9 :(得分:1)
那些不想使用动态内存分配的解决方案(例如嵌入式)
我为嵌入式项目编写了tokenise_to_argc_argv()
,它使用strtok_r()
作为将命令字符串标记为argc和argv形式的基础。与此处的大多数答案不同,我通常静态分配内存。因此,我的实现假定您的上限为argv_length
。对于大多数典型的嵌入式应用程序,这已经足够了。我在下面也包含了示例代码,因此您可以快速使用它。
int tokenise_to_argc_argv(
char *buffer, ///< In/Out : Modifiable String Buffer To Tokenise
int *argc, ///< Out : Argument Count
char *argv[], ///< Out : Argument String Vector Array
const int argv_length ///< In : Maximum Count For `*argv[]`
)
{ /* Tokenise string buffer into argc and argv format (req: string.h) */
int i = 0;
for (i = 0 ; i < argv_length ; i++)
{ /* Fill argv via strtok_r() */
if ( NULL == (argv[i] = strtok_r( NULL , " ", &buffer)) ) break;
}
*argc = i;
return i; // Argument Count
}
\0
插入缓冲区以分隔字符串标记)。" "
空格字符作为唯一的分隔符。这模拟了典型命令行界面中的行为main(int argc, char *argv[])
。strtok_r()
是因为它是线程安全的(因为strtok()
使用内部静态指针)。它也是标准C库string.h
的一部分,因此非常便携。以下是演示代码及其输出。此外,这表明tokenise_to_argc_argv()可以处理大多数字符串情况,因此已经过测试。此函数也不依赖于malloc或calloc,因此适用于嵌入式用法(在使用stdint.h
类型之后)。
演示代码
/*******************************************************************************
Tokenise String Buffer To Argc and Argv Style Format
Brian Khuu 2017
*******************************************************************************/
#include <stdio.h> // printf()
#include <ctype.h> // isprint()
#include <string.h> // strtok_r()
/**-----------------------------------------------------------------------------
@brief Tokenise a string buffer into argc and argv format
Tokenise string buffer to argc and argv form via strtok_r()
Warning: Using strtok_r will modify the string buffer
Returns: Number of tokens extracted
------------------------------------------------------------------------------*/
int tokenise_to_argc_argv(
char *buffer, ///< In/Out : Modifiable String Buffer To Tokenise
int *argc, ///< Out : Argument Count
char *argv[], ///< Out : Argument String Vector Array
const int argv_length ///< In : Maximum Count For `*argv[]`
)
{ /* Tokenise string buffer into argc and argv format (req: string.h) */
int i = 0;
for (i = 0 ; i < argv_length ; i++)
{ /* Fill argv via strtok_r() */
if ( NULL == (argv[i] = strtok_r( NULL, " ", &buffer)) ) break;
}
*argc = i;
return i; // Argument Count
}
/*******************************************************************************
Demonstration of tokenise_to_argc_argv()
*******************************************************************************/
static void print_buffer(char *buffer, int size);
static void print_argc_argv(int argc, char *argv[]);
static void demonstrate_tokenise_to_argc_argv(char buffer[], int buffer_size);
int main(void)
{ /* This shows various string examples */
printf("# `tokenise_to_argc_argv()` Examples\n");
{ printf("## Case0: Normal\n");
char buffer[] = "tokenising example";
demonstrate_tokenise_to_argc_argv(buffer, sizeof(buffer));
}
{ printf("## Case1: Empty String\n");
char buffer[] = "";
demonstrate_tokenise_to_argc_argv(buffer, sizeof(buffer));
}
{ printf("## Case2: Extra Space\n");
char buffer[] = "extra space here";
demonstrate_tokenise_to_argc_argv(buffer, sizeof(buffer));
}
{ printf("## Case3: One Word String\n");
char buffer[] = "one-word";
demonstrate_tokenise_to_argc_argv(buffer, sizeof(buffer));
}
}
static void demonstrate_tokenise_to_argc_argv(char buffer[], int buffer_size)
{ /* This demonstrates usage of tokenise_to_argc_argv */
int argc = 0;
char *argv[10] = {0};
printf("* **Initial State**\n");
print_buffer(buffer, buffer_size);
/* Tokenise Command Buffer */
tokenise_to_argc_argv(buffer, &argc, argv, sizeof(argv));
printf("* **After Tokenizing**\n");
print_buffer(buffer, buffer_size);
print_argc_argv(argc,argv);
printf("\n\n");
}
static void print_buffer(char *buffer, int size)
{
printf(" - Buffer Content `");
for (int i = 0 ; i < size; i++) printf("%c",isprint(buffer[i])?buffer[i]:'0');
printf("` | HEX: ");
for (int i = 0 ; i < size; i++) printf("%02X ", buffer[i]);
printf("\n");
}
static void print_argc_argv(int argc, char *argv[])
{ /* This displays the content of argc and argv */
printf("* **Argv content** (argc = %d): %s\n", argc, argc ? "":"Argv Is Empty");
for (int i = 0 ; i < argc ; i++) printf(" - `argv[%d]` = `%s`\n", i, argv[i]);
}
<强>输出强>
tokenise_to_argc_argv()
示例tokenising example0
| HEX:74 6F 6B 65 6E 69 73 69 6E 67 20 65 78 61 6D 70 6C 65 00 tokenising0example0
| HEX:74 6F 6B 65 6E 69 73 69 6E 67 00 65 78 61 6D 70 6C 65 00 argv[0]
= tokenising
argv[1]
= example
0
| HEX:00 0
| HEX:00 extra space here0
| HEX:65 78 74 72 61 20 20 73 70 61 63 65 20 68 65 72 65 00 extra0 space0here0
| HEX:65 78 74 72 61 00 20 73 70 61 63 65 00 68 65 72 65 00 argv[0]
= extra
argv[1]
= space
argv[2]
= here
one-word0
| HEX:6F 6E 65 2D 77 6F 72 64 00 one-word0
| HEX:6F 6E 65 2D 77 6F 72 64 00 argv[0]
= one-word
以某种方式在工具链中缺少string.h或strtok_r()?
如果由于某种原因你的工具链没有strtok_r()。您可以使用strtok_r()的简化版本。 它是strtok_r()的GNU C实现的修改版本,但简化为仅支持空格字符。
要使用此功能,只需将其置于tokenise_to_argc_argv()
之上,然后替换strtok_r( NULL, " ", &buffer)
与strtok_space(&buffer)
/**-----------------------------------------------------------------------------
@brief Simplied space deliminated only version of strtok_r()
- save_ptr : In/Out pointer to a string. This pointer is incremented by this
function to find and mark the token boundry via a `\0` marker.
It is also used by this function to find mutiple other tokens
via repeated calls.
Returns:
- NULL : No token found
- pointer to start of a discovered token
------------------------------------------------------------------------------*/
char * strtok_space(char **save_ptr)
{ /* strtok_space is slightly modified from GNU C Library `strtok_r()` implementation.
Thus this function is also licenced as GNU Lesser General Public License*/
char *start = *save_ptr;
char *end = 0;
if (*start == '\0') {
*save_ptr = start;
return NULL;
}
/* Scan leading delimiters. */
while(*start == ' ') start++;
if (*start == '\0') {
*save_ptr = start;
return NULL;
}
/* Find the end of the token. */
end = start;
while((*end != '\0') && (*end != ' ')) end++;
if (*end == '\0') {
*save_ptr = end;
return start;
}
/* Terminate the token and make *SAVE_PTR point past it. */
*end = '\0';
*save_ptr = end + 1;
return start;
}
答案 10 :(得分:1)
我写的这个也考虑了引号(但不是嵌套的)
请随时贡献。
/*
Tokenize string considering also quotes.
By Zibri <zibri AT zibri DOT org>
https://github.com/Zibri/tokenize
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int main(int argc, char *argv[])
{
char *str1, *token;
int j;
char *qstart = NULL;
bool quoted = false;
if (argc != 2) {
fprintf(stderr, "Usage: %s string\n", argv[0]);
exit(EXIT_FAILURE);
}
for (j = 1, str1 = argv[1];; j++, str1 = NULL) {
token = strtok(str1, " ");
if (token == NULL)
break;
if ((token[0] == 0x27) || (token[0] == 0x22)) {
qstart = token + 1;
quoted = true;
}
if ((token[strlen(token) - 1] == 0x27) || (token[strlen(token) - 1] == 0x22)) {
quoted = false;
token[strlen(token) - 1] = 0;
printf("%d: %s\n", j, qstart);
} else {
if (quoted) {
token[strlen(token)] = 0x20;
j--;
} else
printf("%d: %s\n", j, token);
}
}
if (quoted) {
fprintf(stderr, "String quoting error\n");
return EXIT_FAILURE;
} else
return EXIT_SUCCESS;
}
示例输出:
$ ./tokenize "1 2 3 '4 5 6' 7 8 \"test abc\" 10 11"
1: 1
2: 2
3: 3
4: 4 5 6
5: 7
6: 8
7: test abc
8: 10
9: 11
答案 11 :(得分:1)
我的项目需要将字符串分成argc
和argv
。
找到了一个非常出色的代码Torek。但是它改变了输入缓冲区,所以我做了一些修改以满足我的需求。
在命令行中输入时,我只花了一点点处理引号混合,因此行为更(不完全)像Linux Shell。
注意:此功能不会编辑原始字符串,因此您可以重复使用输入缓冲区(错误报告等)。
void remove_quote(char* input){
//Implementing yourself to remove quotes so it would be completely like Linux shell
}
size_t cmd_param_split(char *buffer, char *argv[], size_t argv_max_size)
{
char *p, *start_of_word;
int c, i;
enum states { DULL=0, IN_WORD, IN_STRING, QUOTE_DOUBLE,QUOTE_SINGLE } state = DULL;
size_t argc = 0;
int quote = 0;
for (p = buffer; argc < argv_max_size && *p != '\0'; p++) {
c = (unsigned char) *p;
printf("processing %c, state = %d\n", c,state);
switch (state) {
case DULL:
if (isspace(c)) {
continue;
}
if (c == '"' ||c == '\'') {
quote = c;
state = IN_STRING;
start_of_word = p + 1;
continue;
}
state = IN_WORD;
start_of_word = p;
continue;
case IN_STRING:
if (c == '"' || c == '\'') {
if (c!=quote)
continue;
else
quote = 0;
strncpy(argv[argc],start_of_word, p - start_of_word);
remove_quote(argv[argc]);
argc++;
state = DULL;
}
continue;
case IN_WORD:
if(quote==0 && (c == '\"' ||c == '\''))
quote = c;
else if (quote == c)
quote = 0;
if (isspace(c) && quote==0) {
strncpy(argv[argc],start_of_word, p - start_of_word);
remove_quote(argv[argc]);
argc++;
state = DULL;
}
continue;
}
}
if (state != DULL && argc < argv_max_size){
strncpy(argv[argc],start_of_word, p - start_of_word);
remove_quote(argv[argc]);
argc++;
}
if (quote){
printf("WARNING: Quote is unbalanced. This could lead to unwanted-behavior\n");
for(i = 0;i<argc;i++)
printf("arg %d = [%s]\n",i,argv[i]);
printf("Original buffer: [%s]\n",buffer);
}
return argc;
}
int main()
{
int i=0;
int argc;
char* argv[64];
for(i=0;i<64;i++){
argv[i] = malloc(256);
memset(argv[i],0x0,256);
}
char* buffer="1 2 3 \'3 4\"567\' \"bol\'obala\" 2x2=\"foo\"";
argc = cmd_param_split(buffer,argv,64);
for(i = 0;i<argc;i++)
printf("arg %d = [%s]\n",i,argv[i]);
return 0;
}
使用以下字符串进行了测试
1. "1 2 3 \'3 4\"567\' \"bol\'obala\" 2x2=\"foo\""
arg 0 = [1]
arg 1 = [2]
arg 2 = [3]
arg 3 = [3 4"567]
arg 4 = [bol'obala]
arg 5 = [2x2="foo"]
2. "./foo bar=\"Hanoi HoChiMinh\" exp='foo123 \"boo111' mixquote \"hanoi \'s\""
arg 0 = [./foo]
arg 1 = [bar="Hanoi HoChiMinh"]
arg 2 = [exp='foo123 "boo111']
arg 3 = [mixquote]
arg 4 = [hanoi 's]
但是,在RaspberryPi中测试的cmd行中运行时,Linux shell会删除引号,即使是混合大小写,如下所示。
./foo bar="Hanoi HoChiMinh" exp='foo123 "boo111' mixquote "hanoi 's"
arg 0 = [./foo]
arg 1 = [bar=Hanoi HoChiMinh]
arg 2 = [exp=foo123 "boo111]
arg 3 = [mixquote]
arg 4 = [hanoi 's]
因此,如果您真的想模仿整个Linux Shell的行为,那么在上面保留空白时,只需花一点点力气即可删除引号remove_quote()函数。
答案 12 :(得分:0)
不幸的是C ++,但对于其他可能会搜索此类库的人,我建议:
ParamContainer - easy-to-use command-line parameter parser
真的很小很容易。
p.addParam("long-name", 'n', ParamContainer::regular,
"parameter description", "default_value");
programname --long-name = value
cout << p["long-name"];
>> value
根据我的经验: