簡體   English   中英

在C ++中訪問命令行參數

[英]Access command line arguments in C++

是否可以在不通過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/zh-CN/library/ms683156(v=vs.85).aspx

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

是否可以在不通過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聲明為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)可能會解析/proc/self/cmdline但是這樣做是不合理的(在Linux系統上,嘗試在終端上運行od -cx /proc/self/cmdline來猜猜我的意思),因此我仍然建議使用int main(int argc, char**argv)並將argcargv存儲在某些全局或靜態數據中,或者更有可能對程序參數進行一些解析

所以在Linux上,你可以編寫你的GetArgumentCountGetArguments功能(通過解析/proc/self/cmdline ,另見 ),但是這將是愚蠢不使用這樣做 argcargvmain (即使它在技術上是可行的)。 對受虐狂的讀者GetArgumentCountGetArguments這樣一個瘋狂的GetArgumentCountGetArguments來解析/proc/self/cmdline是一種練習。

也許您需要這樣做,因為某些靜態數據的構造函數- main之前運行並在crt0中調用它之前-使用了它們; 但在這種情況下,你的程序的設計是恕我直言非常錯誤的 我不知道Windows是否可以使用類似的骯臟技巧。

如果您真的認為這是個好主意,則可以輕松地將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