Я пытаюсь использовать функцию со следующим объявлением:
extern int stem(struct stemmer * z, char * b, int k)1
Я пытаюсь передать ей строку C ++, поэтому я решил использовать c_str()
функция. Возвращается const char *
, Когда я пытаюсь передать его stem()
функция, я получаю эту ошибку: error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
,
Как я могу сохранить результат c_str () так, чтобы я мог использовать его с stem
функционировать?
Вот код, который я запускаю:
struct stemmer * z = create_stemmer();
char * b = s.c_str();
int res = stem(z, b, s.length()); //this doesn't work
free_stemmer(z);
return s.substr(0,res);
Проблема в том, что c_str()
возвращает буфер, который нельзя изменить (const
), в то время как stem()
может изменить буфер, который вы передаете (не const
). Вы должны сделать копию результата c_str()
получить модифицируемый буфер.
Страница http://www.cplusplus.com/reference/string/string/c_str/ имеет больше информации о C ++ 98 и 11 версиях. Они предлагают заменить char * b = s.c_str();
со следующим:
char * b = new char [s.length()+1];
std::strcpy (b, s.c_str());
Вы не должны пытаться удалить константу строки, возвращаемой c_str()
:
char * b = s.c_str();
но вы можете передать адрес std::string
Внутренний буфер напрямую:
int res = stem(z, static_cast<char*>(&s[0]), s.length());
Если stem()
собирается изменить строку, а затем скопировать ее:
char * scpy= strdup( s.c_str()) ;
int res = stem(z, scpy, strlen( scpy));
free( scpy) ;
Используйте const_cast:
int res = stem(z, const_cast<char*>(s.c_str()), s.length()+1);
free_stemmer(z);
return s.substr(0,res);
Обратите внимание на выражение длины + 1, которое может (или не может) понадобиться. Строки в стиле C (char *) имеют дополнительный нулевой терминатор (нулевой байт, эквивалентный «\ 0») в конце. Ваша функция ствола может (или не может) ожидать нулевой терминатор в конце строки — попробуйте оба варианта.
Также обратите внимание, что функция «stem» не должна пытаться изменить строку, в противном случае могут произойти плохие вещи (предупреждение, основанное на комментарии @David Heffernan)
.c_str()
Просто возвращает указатель на данные, я бы обновил функцию ствола, чтобы принять 'const char*'
если вы не хотите изменять данные в строке, в этом случае вы должны передать их как новый строковый объект.
Если вы не можете редактировать функцию ствола, вы можете привести ее:
int res = stem(z, const_cast<char*>(s.c_str()), s.length());
Это нехорошо, но ничто не мешает тебе
#include <iostream>
#include <string>
using namespace std;
void foo(char *ch)
{
ch[0] = 'B';
}
int main()
{
string str = "helo world";
char *ch = const_cast<char *>(str.c_str());
foo(ch);
// Belo world
cout << str << endl;
return 0;
}