C++中const char*转换为const char* const

4

我正在为我的课堂作业编写一个非常基本的shell程序。目前已经接近完成,但是在使用execvp和参数字符数组时遇到了问题。以下是我的代码片段。

//Split the left content args
istringstream iss(left);
while(getline(iss, s, ' ')){
     v.push_back(s);
}

//Get the split string and put it into array
const char* cmd_left[v.size()+1];
for(unsigned int i = 0; i < v.size(); i++){
     cmd_left[i] = v.at(i).c_str();
}
cmd_left[v.size()] = 0;
v.clear();

这被用于...

execvp(cmd_left[0], cmd_left);

我的错误是

assign3.cxx:96:34: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]

我理解问题在于我的字符数组没有填满常量数据,所以我需要从`const char *`转换为`const char * const`。我读到了`const_cast`的一些内容,但我不确定这是否是我需要做的。
如果您愿意帮助我让我的字符数组正确地被该函数接受,那么请帮忙。如果需要我发布更多的代码,请告诉我。
谢谢
3个回答

1
问题在于你无法将const变量传递给期望非const参数的函数。
换句话说,const char *是char *的子集。
删除const。
/*const*/ char* cmd_left[v.size()+1];

在这里添加 const_cast
cmd_left[i] = const_cast<char *>( v.at(i).c_str() );

你代码的其他部分看起来有些可疑,但这样做可以使它编译通过。


啊,非常感谢。这样就清楚多了。此外,我的代码的其余部分只是将一个字符串拆分成更易处理的形式。也许有更好的方法,但它完成了任务,所以我很满意。 - Zerocaliber

0

没有任何const_cast:

istringstream iss(left);
while(getline(iss, s, ' ')){
     v.push_back(s);
}

//assuming v is not empty! which you were already
string command = v[0]; //store the command in a separate variable (this makes a copy of the string)

char* cmd_left[v.size()+1]; //not a (const char)*
for(unsigned int i = 0; i < v.size(); i++){
     cmd_left[i] = new char[v[i].size()+1];
     strcpy(cmd_left[i], v[i].c_str()); //copy contents of each string onto a new buffer
}
cmd_left[v.size()] = NULL;

v.clear(); //if you really want to; not necessary from the code you posted

//...
execvp(command.c_str(), cmd_left);

v.clear() 实际上是必要的,因为我后来需要重复使用它。但是感谢您向我展示了如何在不进行强制转换的情况下完成它。 - Zerocaliber

0

有时候创建一个包含常量动态数组的任务并不容易,甚至有时是不可能的,因为所有的元素都必须在初始化器 {} 中声明。 但幸运的是,你可以告诉编译器,在某个特定的时间段内,你传递的数组将是常量。你可以这样做,这将产生以下结果:

&((char* const) (const_cast<char*>(cmd_left[0]) ))

内部的const_cast将会去除std::string所拥有的字符数组的常量性。因此,函数可能会在std::string背后更改字符数组的内容。当了解此类参数的函数行为时,这可能是可以接受的。

如果您想创建一个const char*数组,而不是使用const_cast或使用new/delete管理内存,您可以使用std::vector而不是字符串向量。

istringstream iss(left);
while(getline(iss, s, ' ')){
     v.push_back(std::vector<char>(s.length()+1));
     strcpy(&v.back().front(),s.c_str());
}

//Get the split string and put it into array
char* cmd_left[v.size()+1];
for(unsigned int i = 0; i < v.size(); i++){
     cmd_left[i] = &v.at(i).front();
}
cmd_left[v.size()] = 0;
v.clear();
execvp(cmd_left[0], &((char* const)cmd_left[0]));

希望这能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接