简体   繁体   English

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

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

My application has entry point 我的申请有入口点

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

}

I need to extend *argv array to n+1 and append a value. 我需要将*argv数组扩展为n+1并附加一个值。 For example, I need to append "-app_ver" . 例如,我需要附加"-app_ver"

I'm a newcomer in C++ (with Java background). 我是C ++的新手(有Java背景)。 I know that I can't change array size, so I need any solution (any approach copying array, etc.) 我知道我不能改变数组大小,所以我需要任何解决方案(任何方法复制数组等)

To duplicate your argv , you can use a std::vector of pointers to char . 要复制argv ,可以使用指向charstd::vector指针。

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

Then add the new element to it: 然后添加新元素:

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

Then replace argv with the new array: 然后用新数组替换argv

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

Note: at the end of normal arguments, there should be a null pointer. 注意:在普通参数的末尾,应该有一个空指针。 It's rarely used (though it's required by the Standard); 它很少使用(虽然它是标准所要求的); if you are sure your further code doesn't use it, and you only want to add one element to your argv array, you can just overwrite the null pointer, and not use any replacement for argv . 如果您确定您的其他代码不使用它,并且您只想在argv数组中添加一个元素,则可以只覆盖空指针,而不是使用argv任何替换。 That is, disregard all the above code, and just do this: 也就是说,忽略上述所有代码,只需这样做:

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

However, this is dangerous - it will crash if you ever decide to add one more element, and it might crash if some code requires the presence of a null pointer after the last argument. 但是,这很危险 - 如果您决定再添加一个元素,它将崩溃,如果某些代码在最后一个参数后需要存在空指针,它可能会崩溃。

Like cbuchart says, you have to create a new array or maybe a vector. 就像cbuchart说的那样,你必须创建一个新的数组或者一个向量。 Using vector and string object can be more simple than char* and array. 使用vector和string对象可以比char *和array更简单。

Exemple : 例如:

#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
    }

}

The argv is fixed-size block of memory. argv是固定大小的内存块。 You have to copy whole content (all the pointers) to bigger array in order to extend it. 您必须将整个内容(所有指针)复制到更大的数组才能扩展它。 Or just use std::vector<std::string> args; 或者只使用std::vector<std::string> args; and manipulate this variable as it will do it for you. 并操纵这个变量,因为它会为你做。

But to be honest - redesigning your solution could be a good idea - the copying operation might not be necessary. 但说实话 - 重新设计您的解决方案可能是一个好主意 - 复制操作可能没有必要。 Maybe something like std::vector<std::string> additional_parameters; 也许像std::vector<std::string> additional_parameters; will meet your needs? 会满足你的需求吗?

You must construct a new array. 您必须构造一个新数组。 Here an example: 这是一个例子:

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; 

See that I've allocated only the new parameters for the sake of optimization. 看到我为了优化而仅分配了新参数。 To create a full copy you'll have to allocate the memory for the previously existing parameters. 要创建完整副本,您必须为以前存在的参数分配内存。

Just be careful with those manual memory allocations: delete them when finishing. 请注意那些手动内存分配:完成后删除它们。 You only have to delete the ones you've created. 您只需删除您创建的那些。

On the other hand, as argv and argc are usually used in the main function it is not a big deal (the memory-leak). 另一方面,由于argvargc通常用在main函数中,因此它并不是什么大问题(内存泄漏)。

Remarks 备注

As I don't know the future use of these new command line arguments , this solution tries to keep with the original data types of the main function. 由于我不知道将来使用这些新的命令行参数 ,此解决方案会尝试与main函数的原始数据类型保持一致。 If it is passed to Boost or Qt, then the char** cannot be obtained from more direct options such as when using std::vector<std::string> . 如果它被传递给Boost或Qt,那么char**不能从更直接的选项中获得,例如当使用std::vector<std::string> To start with, std::string::c_str() returns a const char* , and those pointers are not consecutive in memory. 首先, std::string::c_str()返回一个const char* ,这些指针在内存中不连续。

A safer option (no manual deletes) can be: 更安全的选项(无手动删除)可以是:

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

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

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