引用使用 argv[] 传入的全局变量
Referencing global variables that are passed in using argv[]
我定义了一些 int 类型的全局变量,我希望它们与命令行参数相匹配,以避免无休止的 if
语句链与 strcmp
。例如,如果我定义了全局变量 myvar
,并且用户键入 myvar
作为命令行参数,我希望能够引用 myvar
并使用 argv[]
。这能做到吗?
编辑我的问题只是为了让它更清楚一点:
目前,我必须这样做:
int* A;
int* B;
int* C;
int set(void)
{
if (strcmp((gargv[2]), "A") == 0)
{
*A = atoi(gargv[3]);
return *A;
}
else if (strcmp((gargv[2]), "B") == 0)
{
*B = atoi(gargv[3]);
return *B;
}
else if (strcmp((gargv[2]), "C") == 0)
{
*C = atoi(gargv[3]);
return *C;
}
else
{
errx(EX_USAGE, "Invalid");
}
}
int main (int argc, char** argv)
{
gargv = argv;
void* mem_chunk = calloc(5, sizeof(int));
A = &mem_chunk[1];
B = &mem_chunk[2];
C = &mem_chunk[3];
if (strcmp(argv[1], "set") == 0)
{
set();
}
}
但是这样做会更简单,我可以将 argv[2]
设置为 argv[3]
,引用全局变量 A、B 或 C:
int* A;
int* B;
int* C;
int set(void)
{
gargv[2] = gargv[3];
// example, if A and 10 given by user then set A = 10 and return
}
int main (int argc, char** argv)
{
gargv = argv;
void* mem_chunk = calloc(5, sizeof(int));
A = &mem_chunk[1];
B = &mem_chunk[2];
C = &mem_chunk[3];
if (strcmp(argv[1], "set") == 0)
{
set();
}
}
你的问题很含糊。当然,您可以根据传递的命令行参数设置全局变量,您可以先 examining/parsing argv
设置所有配置变量。
这实际上是命令行程序的典型结构,参数在程序中先解析后解析,您只使用在解析期间设置的配置值和标志。
还不完全清楚,但我假设您也在寻找工具来简化解析命令行参数。嗯,有很多。在 *nix 系统上,标准库中通常有 getopt()
(在 POSIX 中指定)。请注意,此联机帮助页还描述了 getopt_long()
,一个仅适用于 GNUs C 库 (glibc
) 的 GNU 扩展。
如果 getopt()
对于您的需要来说太简单了,或者您想在 windows 等系统上使用它,请查看一个古老而知名的命令行解析库:popt
。您可能会发现几乎所有具有 google.
的系统的 popt
实现
那么总是有可能 一次 编写您自己的并自己重新使用它。我有 my own 因为我需要一个状态分析的命令行界面,就像脚本语言一样——只是为了给你一个想法。
你的问题让我想到使用这样的命令行:
> yourprogram foo=nanana bar=frobnicate
您想在程序中设置变量 foo
和 bar
。这不是使用带有可选参数和位置参数的开关的 典型 命令行界面,因此 getopt()
不会给你确切的。但是为此编写解析器非常容易,正如这个小演示所示:
#include <stdio.h>
// configuration for the parser:
struct argvVar
{
const char *name; // the name of the variable to look for
const char **value; // the address of the variable to set the value
};
void parseArgvVars(int argc, char **argv, const struct argvVar *vars)
{
// loop over argv:
for (int i = 1; i < argc; ++i)
{
// loop over configuration items:
const struct argvVar *var = vars;
while (var->name)
{
// compare variable name with current argument:
const char *vname = var->name;
const char *arg = argv[i];
while (*arg && *vname)
{
// when different, try the next configured variable:
if (*arg != *vname) goto nextVar;
++arg;
++vname;
}
if (*arg == '=')
{
// when matching and the following sign is an equals sign,
// assign to the variable:
*var->value = arg + 1;
}
nextVar:
++var;
}
}
}
int main(int argc, char **argv)
{
const char *foo = 0;
const char *bar = 0;
const char *baz = 0;
// list of variables we want to assign from argv values:
const struct argvVar vars[] = {
{"foo", &foo},
{"bar", &bar},
{"baz", &baz},
{0, 0} // end of list
};
parseArgvVars(argc, argv, vars);
if (foo) printf("foo: %s\n", foo);
if (bar) printf("bar: %s\n", bar);
if (baz) printf("baz: %s\n", baz);
return 0;
}
尝试了解配置结构的用法和解析函数的通用性质,这样您就可以学会如何一次解决问题并经常重用代码。
您必须使用 getopt() 或 strncmp()。
示例:
strncmp(argv[index], your_string, dim);
我定义了一些 int 类型的全局变量,我希望它们与命令行参数相匹配,以避免无休止的 if
语句链与 strcmp
。例如,如果我定义了全局变量 myvar
,并且用户键入 myvar
作为命令行参数,我希望能够引用 myvar
并使用 argv[]
。这能做到吗?
编辑我的问题只是为了让它更清楚一点:
目前,我必须这样做:
int* A;
int* B;
int* C;
int set(void)
{
if (strcmp((gargv[2]), "A") == 0)
{
*A = atoi(gargv[3]);
return *A;
}
else if (strcmp((gargv[2]), "B") == 0)
{
*B = atoi(gargv[3]);
return *B;
}
else if (strcmp((gargv[2]), "C") == 0)
{
*C = atoi(gargv[3]);
return *C;
}
else
{
errx(EX_USAGE, "Invalid");
}
}
int main (int argc, char** argv)
{
gargv = argv;
void* mem_chunk = calloc(5, sizeof(int));
A = &mem_chunk[1];
B = &mem_chunk[2];
C = &mem_chunk[3];
if (strcmp(argv[1], "set") == 0)
{
set();
}
}
但是这样做会更简单,我可以将 argv[2]
设置为 argv[3]
,引用全局变量 A、B 或 C:
int* A;
int* B;
int* C;
int set(void)
{
gargv[2] = gargv[3];
// example, if A and 10 given by user then set A = 10 and return
}
int main (int argc, char** argv)
{
gargv = argv;
void* mem_chunk = calloc(5, sizeof(int));
A = &mem_chunk[1];
B = &mem_chunk[2];
C = &mem_chunk[3];
if (strcmp(argv[1], "set") == 0)
{
set();
}
}
你的问题很含糊。当然,您可以根据传递的命令行参数设置全局变量,您可以先 examining/parsing argv
设置所有配置变量。
这实际上是命令行程序的典型结构,参数在程序中先解析后解析,您只使用在解析期间设置的配置值和标志。
还不完全清楚,但我假设您也在寻找工具来简化解析命令行参数。嗯,有很多。在 *nix 系统上,标准库中通常有 getopt()
(在 POSIX 中指定)。请注意,此联机帮助页还描述了 getopt_long()
,一个仅适用于 GNUs C 库 (glibc
) 的 GNU 扩展。
如果 getopt()
对于您的需要来说太简单了,或者您想在 windows 等系统上使用它,请查看一个古老而知名的命令行解析库:popt
。您可能会发现几乎所有具有 google.
popt
实现
那么总是有可能 一次 编写您自己的并自己重新使用它。我有 my own 因为我需要一个状态分析的命令行界面,就像脚本语言一样——只是为了给你一个想法。
你的问题让我想到使用这样的命令行:
> yourprogram foo=nanana bar=frobnicate
您想在程序中设置变量 foo
和 bar
。这不是使用带有可选参数和位置参数的开关的 典型 命令行界面,因此 getopt()
不会给你确切的。但是为此编写解析器非常容易,正如这个小演示所示:
#include <stdio.h>
// configuration for the parser:
struct argvVar
{
const char *name; // the name of the variable to look for
const char **value; // the address of the variable to set the value
};
void parseArgvVars(int argc, char **argv, const struct argvVar *vars)
{
// loop over argv:
for (int i = 1; i < argc; ++i)
{
// loop over configuration items:
const struct argvVar *var = vars;
while (var->name)
{
// compare variable name with current argument:
const char *vname = var->name;
const char *arg = argv[i];
while (*arg && *vname)
{
// when different, try the next configured variable:
if (*arg != *vname) goto nextVar;
++arg;
++vname;
}
if (*arg == '=')
{
// when matching and the following sign is an equals sign,
// assign to the variable:
*var->value = arg + 1;
}
nextVar:
++var;
}
}
}
int main(int argc, char **argv)
{
const char *foo = 0;
const char *bar = 0;
const char *baz = 0;
// list of variables we want to assign from argv values:
const struct argvVar vars[] = {
{"foo", &foo},
{"bar", &bar},
{"baz", &baz},
{0, 0} // end of list
};
parseArgvVars(argc, argv, vars);
if (foo) printf("foo: %s\n", foo);
if (bar) printf("bar: %s\n", bar);
if (baz) printf("baz: %s\n", baz);
return 0;
}
尝试了解配置结构的用法和解析函数的通用性质,这样您就可以学会如何一次解决问题并经常重用代码。
您必须使用 getopt() 或 strncmp()。 示例:
strncmp(argv[index], your_string, dim);