Добавление в c * неверного преобразования из const char * в char * " - PullRequest
1 голос
/ 07 декабря 2011

У меня есть функция ниже в файле с именем WiServer.h для Arduino.

GETrequest(uint8* ipAddr, int port, char* hostName, char* URL);

Теперь проблема в том, что мне нужно объединить значение типа int (setting1) с параметром URL char*, таким какнапример, ниже.

"twittermood.php?status=sendTweet&setting1="+setting1

Я получаю ошибку:

недопустимое преобразование из const char * в char *

Как это исправить

Ответы [ 6 ]

9 голосов
/ 07 декабря 2011

Вы получили приличный общий совет C ++, но для особого случая Arduino на 8-битном микроконтроллере AVR, я думаю, вам нужен совет для конкретной платформы:

Среда выполнения Arduino обеспечивает String объект.Ваш вопрос, вероятно, покрыт этими примерами .

Из-за очень ограниченного пространства ОЗУ в Arduino обычно используют специальные атрибуты для помещения константных строк во флэш-память (в основном, в ПЗУ), которая требует различныхИнструкции для доступа.Код AVR, созданный с помощью GCC, обычно создается поверх AVR Libc , который поддерживает работу с набором константных строк и строк ОЗУ.Вы должны быть явными в своем коде и выбирать правильные операции.Это требует, по крайней мере, базового понимания того, как работают строки C и как работают указатели.Я не уверен, какая часть этой хитрости автоматически обеспечивается строкой Arduino, но без этой хитрости все ваши строковые константы в конечном итоге будут скопированы в ОЗУ при загрузке и будут постоянно занимать эти драгоценные байты.

Если пространство ОЗУ становится проблемой или вы работаете с приложением AVR, которое выполняет обширные манипуляции со строками, вам необходимо научиться использовать сочетание операций PGM Space (строковые функции, которые могут работать только для чтениястроки во флэш-памяти) и обычные строковые операции на основе C в стиле C .

6 голосов
/ 07 декабря 2011

Используйте std::string, а не строки C.Используйте строковые потоки , вместо того, чтобы пытаться объединять не строковые значения в строки:

std::ostringstream oss;
oss << "twittermood.php?status=sendTweet&setting1=" << setting1;
use(oss.str()); // or use(oss.str().c_str());

Если для этого API действительно нужна строка не const (учитывая, что длина строки даже не берется, я полагаю, что это просто ошибочный API, игнорирующий const), скопируйте строку в буфер и передайте следующее:

const std::string& str = oss.str(); 
std::vector<char> buffer(str.begin(), str.end());
buffer.push_back('\0');
GETrequest(addr, port, &buffer[0], c);

Какчто действительно происходит, когда вы делаете то, что делаете:

"twittermood.php?status=sendTweet&setting1=" - это rvalue типа char[43], что неявнопреобразует в const char*, указатель на первый символ .К этому вы добавляете целое число, тем самым формируя новый указатель типа const char* , указывающий на некоторую более или менее случайную ячейку памяти .Я полагаю, вы пытаетесь передать это как char* в вашу функцию API, для которой const должно быть отброшено .

Компилятор C ++, однако, никогда не будет неявно отбрасывать const - для вашего же блага.

2 голосов
/ 07 декабря 2011

Используйте std :: string, а не char *, для такого рода работы.Символ char * в C является чрезвычайно простым, и если вы не знакомы с тем, как работает C, его очень легко использовать неправильно.

Если вам нужно использовать char *, посмотрите на strcpy, strcat и snprintf.Но эти функции очень опасны в руках новичка и могут привести к повреждению памяти и сбоям.

1 голос
/ 07 декабря 2011

Используйте std::string вместо char* и, возможно, std::stringstream для вашей конкатенации. Но сначала о ваших ошибках:

Ваша проблема в том, что "twittermood.php?status=sendTweet&setting1=" даст вам const char*, который нельзя косвенно преобразовать в char*. Если вы действительно уверены, что GETrequest не пытается изменить значение параметра URL, вы можете использовать const_cast<char*>(...) в вашей переменной const char*, чтобы отбросить константу. Тем не менее, делайте это только в том случае, если вы абсолютно уверены, что это не изменится (не врите компилятору о константности (или о чем-то действительно)).

Даже если вы сделаете это "twittermood.php?status=sendTweet&setting1="+setting1 не будет делать то, что вы думаете, что он делает. Как я уже сказал, ваша строковая константа даст вам const char*, который не имеет никаких знаний о строковых операциях. Таким образом, добавление int к нему не приведет к согласованию этого int со строкой, но вместо этого сделает некоторую пуантерарифметику, поэтому, если вам повезет, и ваш int был достаточно мал, вы получите только часть URL, иначе вы займусь чем-то совершенно другим.

1 голос
/ 07 декабря 2011

Вы можете использовать ostringstream для этого:

#include <sstream>

// ...

std::ostringstream os;
os << "twittermood.php?status=sendTweet&setting1=" << setting1;

GETrequest(addr, port, hostname, os.str().c_str());
0 голосов
/ 07 декабря 2011

Публикация решения C для полноты:

const char ctext[] = "twittermood.php?status=sendTweet&setting1=";
char text[sizeof(ctext) + 20];
snprintf(text, sizeof(text), "%s%i", ctext, setting1);

Стандартные строки и потоки гораздо приятнее / безопаснее в использовании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...