如何传递字符串向量到execv
How to pass a vector of strings to execv
我发现构建程序参数列表的最简单方法是将其作为字符串向量。然而,execv期望第二个参数是一个字符数组。让它接受字符串向量的最简单方法是什么?
execv()
只接受字符串指针数组。没有办法让它接受其他任何东西。它是一个标准接口,可以从任何宿主语言调用,而不仅仅是c++。
我已经测试了编译这个:
std::vector<string> vector;
const char *programname = "abc";
const char **argv = new const char* [vector.size()+2]; // extra room for program name and sentinel
argv [0] = programname; // by convention, argv[0] is program name
for (int j = 0; j < vector.size()+1; ++j) // copy args
argv [j+1] = vector[j] .c_str();
argv [vector.size()+1] = NULL; // end of arguments sentinel is NULL
execv (programname, (char **)argv);
是的,它可以通过利用vector
使用的内部数组来非常干净地完成。最好不要在vector中使用c++字符串,const_cast
中不要使用字符串字面值,string.c_str()
中不要使用char*
。
这可以工作,因为标准保证它的元素是连续存储的(参见https://stackoverflow.com/a/2923290/383983)
#include <unistd.h>
#include <vector>
using std::vector;
int main() {
vector<const char*> command;
// do a push_back for the command, then each of the arguments
command.push_back("echo");
command.push_back("testing");
command.push_back("1");
command.push_back("2");
command.push_back("3");
// push NULL to the end of the vector (execvp expects NULL as last element)
command.push_back(NULL);
// pass the vector's internal array to execvp
execvp(command[0], const_cast<char* const*>(command.data()));
return 1;
}
代码改编自:如何将vector传递给execvp
执行const_cast
以避免从字符串常量到'char*' '"的过时转换。字符串字面值在c++中实现为const char*
。const_cast
是这里最安全的cast形式,因为它只移除const
而不做任何其他有趣的事情。execvp()
无论如何都不会编辑这些值。
如果你想避免所有的类型转换,你必须把所有的值复制到char*
类型,这使代码变得复杂,这是不值得的。
虽然如果您想传递给execv
/execl
的参数数量是已知的,但用c编写更容易。
execv
的原型为:
int execv(const char *path, char *const argv[]);
这意味着实参列表是指向以空结束的c字符串的指针数组。
你有vector<string>
。找出该向量的大小,并创建一个指向char的指针数组。然后循环遍历vector,并为vector中的每个string
设置数组中对应的元素指向它。
我之前也遇到过同样的问题。
我最终在std::basic_string<char const*>
中构建了参数列表。然后,我调用c_str()
方法,并对结果执行const_cast<char* const*>
,以execv
接受的格式获得列表。
对于组合参数,我使用new
编辑字符串(由普通字符组成的普通字符串;)),获取它们的c_str()
并让它们泄漏。
const_cast
对于移除额外的const
是必要的,因为给定字符串类型的c_str()
方法返回一个char const* const*
iirc。输入这个,我想我可以使用std::basic_string<char*>
,但我想我有一个原因…
我很清楚const
的类型转换和内存泄漏看起来有点粗鲁,确实是不好的做法,但由于execv
取代了整个过程,无论如何都无关紧要。
您不能改变execv的工作方式(无论如何都不容易),但是您可以用您想要的方式重载函数名:
int execv(const string& path, const vector<string>& argv) {
vector<const char*> av;
for (const string& a : argv) {
av.push_back(a.c_str());
av.push_back(0);
return execv(path.c_str(), &av[0]);
}
当然,这可能会引起一些混淆。您最好给它起一个名字,而不是execv()。
NB:我只是随口打进去的。这可能行不通。它甚至可能无法编译;-)
我最后是这样做的:
-
std::vector<std::string>
抓取我需要的所有参数。 - 在
execv()
之前创建std::vector<const char *>
,为所有参数保留足够的空间。 - 使用
std::transform()
转换第二个矢量。 - 使用
const_cast<char* const*>(vec.data())
给execv()
.
变换通过:
std::transform(stringsVec.cbegin(), stringsVec.cend(), charsVec.begin(),
[](const std::string &arg)
{
return arg.c_str();
});
这基本上是@ericcurtin和@Ferruccio的答案的组合。
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用向量的template_back函数
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何通过派生类函数更改基类中的向量
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何将ampl中的集合表示为c++中的向量
- 变量没有改变?通过向量的函数调用
- 迭代时从向量和内存中删除对象
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 计算排序向量的向量中唯一值的计数
- 矩阵向量乘法(cublasDgemv)返回零
- 一对向量构造函数:初始值设定项列表与显式构造
- 将结构向量排序为子组
- 在C++中调整向量中的索引
- 如何传递字符串向量到execv