我的应用程序有入口点。
int main(int argc, char *argv[])
{
}
我需要扩展
*argv
数组到n+1
并追加一个值。例如,我需要追加"-app_ver"
。作为一个C++新手(有Java背景),我知道我不能改变数组大小,因此我需要任何解决方案(复制数组的任何方法等)。
我的应用程序有入口点。
int main(int argc, char *argv[])
{
}
*argv
数组到n+1
并追加一个值。例如,我需要追加"-app_ver"
。要复制您的argv
,可以使用指向char
的指针的std::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";
然而,这种方法很危险——如果您决定添加一个以上的元素,它将会崩溃;并且,如果某些代码要求在最后参数之后存在空指针,则可能会导致崩溃。像cbuchart所说的,您需要创建一个新的数组或向量。使用向量和字符串对象比使用char *和数组更加简单。
示例:
#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
}
}
QCoreApplication
)需要char**
,这不能直接从std::vector<std::string>
获得。否则,这里描述的方法是一种动态且安全的解决方案。 - cbuchartargv是固定大小的内存块。您必须将整个内容(所有指针)复制到更大的数组中才能扩展它。或者只需使用std::vector<std::string> args;
并操纵此变量,它将为您完成。
但说实话,重新设计您的解决方案可能是一个好主意-复制操作可能是不必要的。也许像std::vector<std::string> additional_parameters;
这样的东西可以满足您的需求?
std::vector<std::string>
简化了复制过程,但某些API需要char **
(例如Qt中的QCoreApplication
),而且不能直接从向量获取。如果原始的char**
不是必需的,则您的方法很好。 - cbuchart你必须构建一个新的数组。这里是一个例子:
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;
为了优化,我只分配了新参数。要创建完整的副本,您需要为先前存在的参数分配内存。
手动分配内存时要小心:完成后删除它们。您只需要删除自己创建的那些。
另一方面,由于argv
和argc
通常在main
函数中使用,所以这不是什么大问题(内存泄漏)。
备注
由于我不知道这些新的命令行参数的未来用途,因此此解决方案尝试保持main
函数的原始数据类型。如果传递给Boost或Qt,则无法从更直接的选项(例如使用std :: vector<std :: string>
)获取char **
。首先,std :: string :: c_str()
返回一个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());
std::vector<std::string>
或std::vector<std::string_view>
中,然后在需要时添加新值? - KABoissonneaultargc + 2
的char *
数组,从argv[]
中复制原始的argc
个字符串,然后将您的额外值和最后一个NULL
添加到数组的最后两个元素中。 - Paul R