如何将值附加到命令行参数数组?

How to append a value to the array of command line arguments?

我的应用程序有入口点

int main(int argc, char *argv[])
{

}

我需要将 *argv 数组扩展到 n+1 并附加一个值。例如,我需要附加 "-app_ver".

我是 C++ 的新手(具有 Java 背景)。我知道我无法更改数组大小,所以我需要任何解决方案(任何复制数组的方法等)

argv 是固定大小的内存块。您必须将整个内容(所有指针)复制到更大的数组才能扩展它。或者只使用 std::vector<std::string> args; 并操纵这个变量,因为它会为你做。

但说实话 - 重新设计您的解决方案可能是个好主意 - 复制操作可能不是必需的。也许像 std::vector<std::string> additional_parameters; 这样的东西可以满足您的需求?

您必须构造一个新数组。举个例子:

int new_argc = argc + 2;
char** new_argv = new char*[new_argc];
new_argv[argc + 1] = nullptr;
for (int ii = 0; ii < argc; ++ii) {
  new_argv[ii] = argv[ii];
}
new_argv[argc] = new char[strlen("-app_ver") + 1]; // extra char for null-terminated string
strcpy(new_argv[argc], "-app_ver");

// use new_argc and new_argv

delete[] new_argv[argc];
delete[] new_argv; 

看到为了优化,我只分配了新参数。要创建完整副本,您必须为以前存在的参数分配内存。

小心那些手动内存分配:完成后删除它们。你只需要删除你创建的那些。

另一方面,argvargc 通常用在 main 函数中,这不是什么大问题(内存泄漏)。

备注

由于我不知道这些新的 命令行参数 的未来用途,此解决方案试图与 main 函数的原始数据类型保持一致。如果它传递给 Boost 或 Qt,那么 char** 无法从更直接的选项中获得,例如使用 std::vector<std::string> 时。首先,std::string::c_str() returns a const char*,这些指针在内存中是不连续的。

一个更安全的选项(没有手动删除)可以是:

int new_argc = argc + 1;
std::vector<std::unique_ptr<char>> new_argv_aux(new_argc); // automatically destroyed
for (int ii = 0; ii < argc; ++ii) {
  new_argv_aux[ii].reset(new char[strlen(argv[ii]) + 1]);
  strcpy(new_argv_aux[ii].get(), argv[ii]);
}
new_argv_aux[argc].reset(new char[strlen("-app_ver") + 1]);
strcpy(new_argv_aux[argc].get(), "-app_ver");

// Now the actual double pointer is extracted from here
std::vector<char*> new_argv(new_argv_aux.size());
for (size_t ii = 0; ii < new_argv_aux.size(); ++ii) {
  new_argv[ii] = new_argv_aux[ii].get(); // soft-reference
} // last element is null from std::unique_ptr constructor

use_here(new_argc, new_argv.data());

如 cbuchart 所说,您必须创建一个新数组或向量。 使用 vector 和 string 对象可以比 char* 和 array 更简单。

例子:

#include <vector>
#include <string>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    vector<string> list;
    for ( int i = 1 ; i < argc ; i++){
        string tmp (argv[i]);
        list.push_back(tmp); // add all arguments to the vector
    }

    cout << "number of given arguments : " << list.size() << endl;

    list.push_back("-app_ver"); // add one string to the vector

    for ( int i = 0 ; i < list.size() ; i++){
        cout << list[i] << endl; // acces data of the vector
    }

}

要复制您的 argv,您可以使用指向 charstd::vector 个指针。

std::vector<const char*> new_argv(argv, argv + argc);

然后向其中添加新元素:

new_argv.push_back("-app_ver");
new_argv.push_back(nullptr); // or NULL if you are using an old compiler

然后用新数组替换argv

argv = new_argv.data(); // or &new_argv[0] if you are using an old compiler
argc = argc + 1;

注意:在正常参数的末尾,应该有一个空指针。它很少被使用(尽管它是标准所要求的);如果您确定您的进一步代码不使用它,并且您只想将一个元素添加到您的 argv 数组,您可以只覆盖空指针,而不使用任何替代 argv。也就是忽略上面所有的代码,直接这样做:

argv[argc++] = "-app_ver";

但是,这很危险 - 如果您决定再添加一个元素,它会崩溃,如果某些代码要求在最后一个参数后存在空指针,它可能会崩溃。