简体   繁体   English

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

[英]Access command line arguments in C++

Is it possible to get the command line arguments without receiving them via int main(int, char**)? 是否可以在不通过int main(int,char **)接收命令行参数的情况下获取命令行参数? I don't want to pass the arguments to multiple methods, so a global function would be perfect. 我不想将参数传递给多个方法,因此全局函数将是完美的。 Also, I do not want to store the arguments by myself via global variables. 另外,我不想自己通过全局变量存储参数。 I'm running Windows and Linux. 我正在运行Windows和Linux。

edit: Example: 编辑:示例:

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

edit: It's possible to use LPTSTR WINAPI GetCommandLine(void); 编辑:可以使用LPTSTR WINAPI GetCommandLine(void); in win32. 在Win32中。

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

I'm looking for equivalent functions in Linux. 我正在寻找Linux中的等效功能。

Is it possible to get the command line arguments without receiving them via int main(int, char**) ? 是否可以在不通过int main(int, char**)接收命令行参数的情况下获取命令行参数?

Yes, with platform-specific functions. 是的,具有特定于平台的功能。 But that's not necessary (see below). 但这不是必需的(见下文)。

I don't want to pass the arguments to multiple methods, 我不想将参数传递给多个方法,

That's understandable. 这是可以理解的。 It's an anti-pattern also known as "tramp data". 这是一种反模式,也称为“流水数据”。

Also, I do not want to store the arguments by myself via global variables. 另外,我不想自己通过全局变量存储参数。

Yes, global variables are rarely a good idea. 是的,全局变量很少是一个好主意。

Here's an alternative approach: store them as a static local container object in some globally available non-member function which returns the container by reference. 这是一种替代方法:将它们作为static本地容器对象存储在某些全局可用的非成员函数中,该函数通过引用返回容器。

Example: 例:

#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();
}

Of course, this can be made more sophisticated. 当然,这可以变得更加复杂。 For example, you might want to prevent anyone else but main from changing the vector by wrapping the vector in a class and declaring main as a friend , something like this: 例如,您可能希望通过将向量包装在类中并将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();
}

Note that special care is needed to avoid bugs at program shutdown, when static objects are destroyed. 请注意,当静态对象被破坏时,需要特别注意避免程序关闭时的错误。 You must make sure that no destructor of a static object accesses Arguments , or else you risk undefined behaviour. 您必须确保没有静态对象的析构函数访问Arguments ,否则您将面临未定义行为的风险。

Is it possible to get the command line arguments without receiving them via int main(int, char**) ? 是否可以在不通过int main(int,char **)接收命令行参数的情况下获取命令行参数?

No (at least, not in portable manner ), however you could put the usual argc , argv into some global variable (or other global data, often after parsing). 否(至少不是以可移植的方式 ),但是您可以将通常的argcargv放入某些全局变量(或其他全局数据,通常在解析之后)。 And that could also be into some static data with other functions in the same translation unit retrieving it. 并且这也可能是一些static数据,而同一 翻译单元中的其他功能则在检索这些数据。 Hence a reasonable (readable and portable) approach would be: 因此,合理的(可读和可移植的)方法将是:

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....

Notice that on some systems or some implementations you might access to the command line arguments in some other ways. 请注意,在某些系统或某些实现中,您可能会通过其他方式访问命令行参数。

dirty Linux specific tricks 肮脏的Linux特技

For example, on Linux, using proc(5) , you might parse /proc/self/cmdline but it is unreasonable to do that (on your Linux system, try to run od -cx /proc/self/cmdline in your terminal to guess what I mean), so I still recommend using int main(int argc, char**argv) and storing, in some global or static data, the argc and argv , or more probably, do some parsing of program arguments . 例如,在Linux上,使用proc(5)可能会解析/proc/self/cmdline但是这样做是不合理的(在Linux系统上,尝试在终端上运行od -cx /proc/self/cmdline来猜猜我的意思),因此我仍然建议使用int main(int argc, char**argv)并将argcargv存储在某些全局或静态数据中,或者更有可能对程序参数进行一些解析

So on Linux, you might code your GetArgumentCount and GetArguments functions (by parsing /proc/self/cmdline , see also this ) but it would be foolish to do so without using argc and argv from main (even if it is technically doable). 所以在Linux上,你可以编写你的GetArgumentCountGetArguments功能(通过解析/proc/self/cmdline ,另见 ),但是这将是愚蠢不使用这样做 argcargvmain (即使它在技术上是可行的)。 Coding such a crazy GetArgumentCount and GetArguments which parses /proc/self/cmdline is left as an exercise to the masochistic reader. 对受虐狂的读者GetArgumentCountGetArguments这样一个疯狂的GetArgumentCountGetArguments来解析/proc/self/cmdline是一种练习。

Perhaps you need that because some static data's constructor -running before main and called before it from crt0 - uses them; 也许您需要这样做,因为某些静态数据的构造函数- main之前运行并在crt0中调用它之前-使用了它们; but in that case, your program's design is IMHO very wrong . 但在这种情况下,你的程序的设计是恕我直言非常错误的 I have no idea if similar dirty tricks are doable in Windows. 我不知道Windows是否可以使用类似的肮脏技巧。

If you really think that is a good idea, you can easily make cor command line arguments global: 如果您真的认为这是个好主意,则可以轻松地将cor命令行参数设为全局:

int argc_ = 0;
char** argv_ = NULL;

int main(int argc, char* argv[]) {
    argc_ = argc;
    argv_ = argv;

    // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM