简体   繁体   中英

Adding to c* invalid conversion from const char* to char*"

I have the function below in a file called WiServer.h for Arduino.

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

Now the problem is I need to concatenate an int value (setting1) to the char* URL parameter like the below for example.

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

I get an error:

invalid conversion from const char* to char*

How do I fix it?

You've gotten decent generic C++ advice, but for the special case of Arduino on an 8-bit AVR microcontroller I think you need platform-specific advice:

The Arduino runtime provides a String object. Your question is probably covered by these examples .

Because of the very limited RAM space on Arduino it is common to use special attributes to put constant strings in flash (essentially ROM) which requires different instructions to access. AVR code built with GCC is typically built on top of AVR Libc which has support for operating on a mix of constant strings and RAM strings. You must be explicit in your code and choose the right operations. This requires at least a basic understanding of how C strings work and how pointers work. I'm not sure how much of this cleverness is automatically provided by the Arduino String, but without this cleverness all of your string constants will end up copied into RAM at boot and will take up those precious bytes all the time.

If RAM space becomes a problem or you are working on an AVR application that does extensive string manipulation you need to learn how to use the mix of PGM Space operations (string functions that can work on read-only strings in flash) and regular C-style RAM-based string operations .

Use std::string , rather than C strings. Use string streams , rather than trying to concatenate non-string values to strings:

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

If that API really needs a non- const string (given that it doesn't even take the length of the string, I suppose it's just a buggy API disregarding const ), copy the string to a buffer and pass that:

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

As for what really happens when you do what you do:

"twittermood.php?status=sendTweet&setting1=" is an rvalue of the type char[43] , which implicitly converts to const char* , a pointer to the first character . To that you add an integer, by this forming a new pointer of the type const char* pointing to some more or less random memory location . I suppose you try to pass this as the char* to your API function, for which the const would have to be dropped .

A C++ compiler, however, will never implicitly drop a const — for your own good.

Use a std::string, not a char*, for this sort of work. A char* in C is extremely basic and if you're not familiar with how C works, very easy to use wrong.

If you need to use char*, look into strcpy, strcat and snprintf. But these functions are very dangerous in a novice's hands and can lead to memory corruption and crashing.

You can use an ostringstream for this:

#include <sstream>

// ...

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

GETrequest(addr, port, hostname, os.str().c_str());

Use std::string instead of char* and maybe a std::stringstream for your concatination. But first about your errors:

Your problem is that "twittermood.php?status=sendTweet&setting1=" will get you a const char* , which can't be implicitely converted to a char* . If you are really sure that GETrequest doesn't try to change the value of its URL parameter, you can use const_cast<char*>(...) on your const char* variable to cast away the constness. However, do this only if you are absolutely sure it won't be changed (don't lie to the compiler about constness (or anything really)).

Even if you do that "twittermood.php?status=sendTweet&setting1="+setting1 won't do what you think it does. As I said your string constant will give you a const char* , which doesn't have any knowledge about string operations. So adding an int to it won't concat that int to the string, but instead do some pointerarithmetic, so if you are lucky and your int was small enough you get only a part of the URL, otherwise you will address something completely different.

Posting C solution for completeness:

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

std strings and streams are much nicer/safer to use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM