是否可以通过int main(int,char **)获取命令行参数而不接收它们?我不想将参数传递给多个方法,因此全局函数将是完美的。另外,我不想通过全局变量自己存储参数。我正在运行Windows和Linux。
修改 例如:
int main()
{
int argc = GetArgumentCount();
char ** argv = GetArguments();
return 0;
}
修改 可以在win32中使用 LPTSTR WINAPI GetCommandLine(void); 。
https://msdn.microsoft.com/en-us/library/ms683156(v=vs.85).aspx
我正在寻找Linux中的等效功能。
答案 0 :(得分:3)
是否可以通过int main(int,char **)获取命令行参数而不接收它们?
否(至少,不是以便携式方式),但是您可以将通常的argc
,argv
放入某些全局变量中(或其他全局数据,通常在解析之后)。这也可能是一些static
数据,其中相同 translation unit中的其他函数检索它。因此,合理(可读和可移植)的方法是:
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上,使用proc(5),您可能会解析/proc/self/cmdline
但这样做是不合理的(在Linux系统上,尝试在终端中运行od -cx /proc/self/cmdline
进行猜测我的意思是,所以我仍然建议使用int main(int argc, char**argv)
并在某些全局或静态数据中存储argc
和argv
,或者更可能的是,执行一些parsing of program arguments。
因此,在Linux上,您可以编写GetArgumentCount
和GetArguments
函数代码(通过解析/proc/self/cmdline
,另请参阅this)但这样做是愚蠢的所以而不使用argc
中的argv
和main
(即使技术上可行)。编码如此疯狂的GetArgumentCount
和GetArguments
解析/proc/self/cmdline
留给了受虐狂的读者。
也许你需要它,因为一些静态数据的构造函数 - 在 main
之前运行并在crt0之前调用它 - 使用它们;但在这种情况下,你的程序的设计是恕我直言非常错误。我不知道在Windows中是否可以使用类似的脏技巧。
答案 1 :(得分:3)
是否可以在不接收的情况下获取命令行参数 他们通过
int main(int, char**)
?
是的,具有特定于平台的功能。但这没有必要(见下文)。
我不想将参数传递给多个方法,
这是可以理解的。这是一种反模式,也被称为“流浪汉数据”。
另外,我不想通过全局变量自己存储参数。
是的,全局变量很少是个好主意。
这是另一种方法:将它们作为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
之外的任何人通过将向量包装在类中并将main
声明为friend
来更改向量,如下所示:
#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
,否则您将面临未定义的行为风险。
答案 2 :(得分:1)
如果您真的认为这是一个好主意,您可以轻松地将cor命令行参数设为全局:
int argc_ = 0;
char** argv_ = NULL;
int main(int argc, char* argv[]) {
argc_ = argc;
argv_ = argv;
// ...
}