可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
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());
回答5:
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.
回答6:
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.