C++ const char* В const char* const

В настоящее время я пишу задание для своего класса, которое должно действовать как очень простая оболочка. Я почти закончил, но у меня возникла проблема с 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, но я не был уверен, что это то, что мне нужно делать.

Если вы будете так любезны, не могли бы вы помочь мне правильно принять мой массив массивов символов этой функцией? Если вам нужно, чтобы я опубликовал больше моего кода, дайте мне знать.

Спасибо


person Zerocaliber    schedule 12.04.2013    source источник


Ответы (3)


Проблема в том, что вы не можете передать константную переменную в функцию, ожидающую неконстантный аргумент.

Другими словами, const char * является подмножеством char *.

удалить const

/*const*/ char* cmd_left[v.size()+1];

добавьте const_cast сюда

cmd_left[i] = const_cast<char *>( v.at(i).c_str() );

другие части вашего кода выглядят подозрительно, но это заставит его скомпилироваться

person yngccc    schedule 12.04.2013
comment
Ах, большое спасибо. Это имеет гораздо больше смысла. Кроме того, остальная часть моего кода просто предназначена для разделения строки в более управляемую форму. Может быть, есть лучший способ сделать это, но это завершает задание, так что я доволен. - person Zerocaliber; 12.04.2013

Без какого-либо 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);
person maditya    schedule 12.04.2013
comment
v.clear() на самом деле оказывается необходимым, потому что я буду использовать его позже. Но спасибо, что показали мне, как это сделать без кастинга. - person Zerocaliber; 12.04.2013

Непросто, а иногда и невозможно создать постоянный динамический массив элементов, потому что все элементы должны быть объявлены в инициализаторе {}. Но, к счастью, вы можете сказать компилятору, что массив, который вы передаете, будет константным, по крайней мере, в течение определенного времени. Вы можете сделать следующее, это даст

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

Надеюсь это поможет.

person nanda    schedule 12.04.2013