在 main() 之外处理 argc 和 argv



如果我想将用于处理命令行参数的大部分代码保留在main之外(用于组织和更具可读性的代码),最好的方法是什么?

void main(int argc, char* argv[]){
//lots of code here I would like to move elsewhere
}

将它们作为参数传递,或将它们存储在全局变量中。 只要您不从 main 返回并尝试在全局范围内的对象的atexit处理程序或析构函数中处理它们,它们仍然存在,并且可以从任何范围访问。

例如:

// Passing them as args:
void process_command_line(int argc, char **argv)
{
// Use argc and argv
...
}
int main(int argc, char **argv)
{
process_command_line(argc, argv);
...
}

或者:

// Global variables
int g_argc;
char **g_argv;
void process_command_line()
{
// Use g_argc and g_argv
...
}
int main(int argc, char **argv)
{
g_argc = argc;
g_argv = argv;
process_command_line();
...
}

将它们作为参数传递是一个更好的设计,因为它是封装的,如果你想要或轻松地将程序转换为库,可以修改/替换参数。 全局变量更容易,因为如果您有许多不同的函数出于任何原因访问 args,您只需存储一次,而无需在所有不同函数之间传递它们。

在可行的情况下,人们应该保持标准。因此,不要写

void main

从来都不是有效的 C 或 C++,而是写

int main

有了它,您的代码可以使用例如g++(使用常用的编译器选项)。

鉴于void main我怀疑Windows环境。无论如何,为了支持在Windows环境中使用程序,您不应该在Windows中使用main参数。它们在 *nix 中工作,因为它们是在该环境中设计的,并且是为该环境设计的;它们通常不适用于 Windows,因为默认情况下(按照非常严格的约定)它们被编码为 Windows ANSI,这意味着它们不能使用用户当前区域设置之外的字符对文件名进行编码。

因此,对于Windows,您最好使用GetCommandLineAPI函数及其姐妹解析函数。为了可移植性,最好将其封装在一些命令行参数模块中。然后你需要处理在Windows中使用wchar_t并在*nix中使用char的有趣问题......

无论如何,我不确定相应的 *nix API,或者即使有一个,但谷歌一下。在最坏的情况下,对于 *nix,您始终可以从main初始化命令行参数模块。*nix 的丑陋直接源于需要通过C++最不可移植的、特定于操作系统的结构(即标准main)来支持可移植性。

只需将argcargv作为要在其中处理它们的函数的参数传递即可。

void parse_arg(int argc, char *argv[]);

Linux 提供program_invocation_nameprogram_invocation_name_short

查看"getoptlong"系列函数和库。 它们提供了一种结构化的方式来定义程序期望的参数,然后可以随时为您解析它们。 还可以帮助生成文档/帮助响应。

它是UNIX世界中的一个旧库,C#中也有一个.Net实现。(+ Perl,Ruby,可能还有更多。 很高兴有一个可用于所有这些的单一范式! 一次学习,随处使用!

最新更新