访问C++中的命令行参数

Access command line arguments in C++

本文关键字:命令行 参数 C++ 访问      更新时间:2023-10-16

是否可以在不通过int main(int,char**)接收命令行参数的情况下获取命令行参数?我不想把参数传递给多个方法,所以全局函数是完美的。此外,我不想自己通过全局变量存储参数。我正在运行Windows和Linux。

编辑:示例:

int main()
{
int argc = GetArgumentCount();
char ** argv = GetArguments();
return 0;
}

编辑:可以使用LPTSTR WINAPI GetCommandLine(void)在win32中。

https://msdn.microsoft.com/en-us/library/ms683156(v=vs.85).aspx

我正在Linux中寻找等效的功能。

是否可以在不接收通过CCD_ 1?

是,具有特定于平台的功能。但这并不是必须的(见下文)。

我不想将参数传递给多个方法,

这是可以理解的。这是一种反模式,也称为"不定期数据"。

此外,我不想通过全局变量自己存储参数。

是的,全局变量很少是个好主意。

这里有一种替代方法:将它们作为static本地容器对象存储在某个全局可用的非成员函数中,该函数通过引用返回容器。

示例:

#include <iostream>
#include <string>
#include <vector>
std::vector<std::string>& Arguments()
{
static std::vector<std::string> arguments;
return arguments;
}
void f()
{
// use arguments anywhere else:
std::cout << Arguments()[0];
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments().push_back(argv[i]);
}
f();
}

当然,这可以变得更加复杂。例如,您可能希望通过将向量封装在类中并将main声明为friend来防止除main之外的任何其他人更改向量,类似于以下内容:

#include <iostream>
#include <string>
#include <vector>
class Arguments final
{
public:
static int Count()
{
return arguments.size();
}
static std::string Get(int index)
{
return arguments[index];
};
private:
Arguments() = delete;
friend int main(int argc, char* argv[]);
static std::vector<std::string> arguments;
};
std::vector<std::string> Arguments::arguments;
void f()
{
// use Arguments anywhere else:
std::cout << Arguments::Get(0);
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments::arguments.push_back(argv[i]);
}
f();
}

请注意,当静态对象被破坏时,需要特别注意避免程序关闭时出现错误。您必须确保没有静态对象的析构函数访问Arguments,否则您将面临未定义行为的风险。

是否可以在不通过int main(int,char**)接收命令行参数的情况下获取命令行参数?

否(至少,不是以可移植的方式),但是您可以将常见的argcargv放入一些全局变量(或其他全局数据,通常在解析后)。这也可能被转换到一些static数据中,而同一翻译单元中的其他功能正在检索它。因此,一种合理的(可读且可移植的)方法是:

static int myargc;
static char **myargv;
int GetArgumentCount(void) {
return myargc;
}
char**GetArguments(void) {
return myargv;
}
int main(int argc, char**argv) {
myargc= argc;
myargv= argv;
/// etc....

请注意,在某些系统或某些实现中,您可能会以其他方式访问命令行参数。

肮脏的Linux特定的技巧

例如,在Linux上,使用proc(5),您可能会解析int main(int, char**)0,但这样做是不合理的(在Linux系统上,尝试在终端中运行od -cx /proc/self/cmdline来猜测我的意思),所以我仍然建议使用int main(int argc, char**argv),并在一些全局或静态数据中存储argcargv,或者更可能的是,对程序参数进行一些解析。

因此,在Linux上,您可能会对GetArgumentCountGetArguments函数进行编码(通过解析/proc/self/cmdline,另请参阅此内容),但如果不使用main中的argcargv(即使在技术上可行),那么这样做是愚蠢的。编码这样一个疯狂的GetArgumentCount和解析/proc/self/cmdlineGetArguments留给受虐狂读者作为练习。

也许你需要这样做,因为一些静态数据的构造函数-在main之前运行并在它之前从crt0调用-使用它们;但在这种情况下,您的程序的设计是IMHO非常错误的。我不知道类似的肮脏伎俩在Windows中是否可行

如果你真的认为这是个好主意,你可以很容易地将cor命令行参数设置为全局参数:

int argc_ = 0;
char** argv_ = NULL;
int main(int argc, char* argv[]) {
argc_ = argc;
argv_ = argv;
// ...
}