Как преобразовать `const char *` в просто `char *`? - PullRequest
4 голосов
/ 17 мая 2011

Я использую библиотеку pdCurses и собираюсь реально использовать только строки в моей консольной игре C ++, но функция curses mvinstr() или любая функция вставки требует неконстантного char * в качестве параметра.

  • Сначала я решил эту проблему, просто введя string.c_str(), но это возвращает const char *, который, очевидно, не работает с функцией.
  • Далее я ставлю (char *)string.c_str(), но это вызывает только необработанное исключение.
  • Наконец, я только что попробовал char *test = string.c_str(), но это также не совместимо с const.

Чтомне сделать, чтобы решить эту проблему?

K Я только что попробовал const_cast (), и я все еще получаю исключение и прерывание .... Я не знаю, почему PDcurses принимает только неконстантные указатели на символы .... = (

хорошо, создание буфера char * не работало, когда я использовал этот код (time_s - это жало):

size_t length; 
    char buffer[12]; 
    length=time_s.copy(buffer,5,0); 
    buffer[length]='\0';
mvinstr(time_loc_y, time_loc_x, buffer);

я даже поставил остановку перед mvinstr () ипроверил содержимое буфера, которое было «00/0», именно то, что я хотел.

, но я получил точку нарушения доступа к «xutility» ....

Ответы [ 7 ]

7 голосов
/ 17 мая 2011

mvinstr(x,y,str) и другие "принимают символы (или широкие символы) из текущей или указанной позиции в окне и возвращают их в виде строки в str (или wstr)."

Функция фактически изменит строку, поэтому вы не можете безопасно отбрасывать const, тем более что c_str указывает, что вы не должны изменять возвращаемую строку.

Вам нужно что-то вроде:

const MAX = 100;
char buf[MAX];
mvinnstr(x, y, buf, MAX);
...error checking...
string s = buf;

Обратите внимание, что я избегал mvinstr в пользу mvinnstr, чтобы избежать возможности переполнения буфера.

3 голосов
/ 17 мая 2011

Как насчет

char* buffer = &str[0];
int fetched_len = mvinnstr(time_loc_y, time_loc_x, buffer, str.size());
str.resize(fetched_len);

В общем, вы должны создать буфер для записи вместо удаления const из указателя, который его имеет. например,

vector<char> charvec(MAX_LENGTH);
str = string(&charvec[0], mvinnstr(time_loc_y, time_loc_x, &charvec[0], charvec.size());
2 голосов
/ 17 мая 2011

Осторожно - если код, использующий данные was- const, пытается его изменить, может произойти все что угодно.

Короче:

const std::string str = "...";
char *caution = const_cast<char *>(str.c_str());

Однако, учитывая, что выполучая необработанные исключения, вам, вероятно, нужно сделать модифицируемую копию константной строки перед вызовом mvinstr().Может быть:

const std::string str = "...";
char *caution = new char[str.length()+1];
str.copy(caution, str.length()+1);
...call to mvinstr()...
delete[] caution;
1 голос
/ 17 мая 2011

Попробуйте что-то вроде следующего, затем используйте buffer, где вам нужно char*. Как уже упоминал Бен, вам нужно быть очень осторожным, чтобы размер буфера был больше, чем строка плюс нулевой терминатор.

const int BUFFER_SIZE = 255;

string str ("Your string");
char buffer[BUFFER_SIZE];
if (str.length() < BUFFER_SIZE)
{
    size_t copy_length;
    copy_length=str.copy(buffer,str.length(),0);
    buffer[copy_length]='\0';
}
1 голос
/ 17 мая 2011

Поскольку mvinstr фактически хранит данные в массиве, указанном char*, вы не можете использовать string там. Вам нужно выделить массив char, передать его в mvinstr, а затем перенести символы в string, если хотите.

Если вы использовали функцию, которая могла быть объявлена ​​с const char * (то есть фактически она не изменяет массив), то вы могли бы использовать const_cast<> для удаления const.

const_cast<char *>(str.c_str());

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

0 голосов
/ 17 мая 2011

if (string.empty()) foo(const_cast<char*>(string.c_str());

лучший, но все же злой способ удаления const - const_cast (const_string);(лучше найти через grep / search)

Исключение для ведьмы вы встречали?Ты просто читаешь char * или меняешь значения?если вы измените его, вам следует изменить код.

const char* test = string.c_str(); Не создает глубокую копию строки, только указатель на внутреннее представление данных string.data ().

=> (предложение) найти книгу по C ++, где вы можете получить более глубокое представление о c ++.Или что-то вроде C ++.

0 голосов
/ 17 мая 2011

Удаление const можно выполнить с помощью const_cast, и иногда это необходимо для использования устаревших интерфейсов, которые были написаны на C и не используют const.В таких случаях вы можете сделать:

char* ptr = const_cast<char*> (str.c_str());

Тем не менее, со справочной страницы cplusplus на c_str ():

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

Это означает, что вы обязаны убедиться, что ptr не используется для изменения строки, а вы должны обрабатывать время жизни ptr соответственно.Т.е. вы не можете продолжать использовать ptr после того, как str выйдет из области видимости или после вызова любых неконстантных методов для str.Если вы сделаете это, вы войдете в Undefined Behavior и, скорее всего, потерпите крах.

Если вы ищете безопасный способ взаимодействия с устаревшим интерфейсом, который принимает char*, вы можете сделать свою собственную записываемую копию:

char* ptr = new char[ str.size() + 1 ];
strcpy(ptr, str.c_str());
ptr[str.size()] = '\0';
// ... use ptr as much as you want...
delete [] ptr;
...