1

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?

4
  • 5
    Since you're not familiar with C++ I'll recommend a good introductory C++ book. Commented Dec 7, 2011 at 18:13
  • 4
    How in the world is that "not a real question"? I really sympathize with all the resentments of a seasoned C++ programmer against clueless Java coders being unleashed onto the C++ world, and have seen my share of such code — but it's a legitimate question according to the rules, and as an SO question it's not a bad one. Commented Dec 7, 2011 at 18:25
  • Coming from Java to C/C++ is tricky for us Java programmers. As much as I would love to learn C/C++, i'm doing a project in Arduino and came across this slight problem with pointers. I didn't expect to have these sort of responses and down votes and basically be told to F off and read a C++ Book. Commented Dec 7, 2011 at 18:37
  • 1
    @FailedDev: I wasn't replying to you, I was addressing whoever had cast that <censored> close vote and to those who casted the downvotes. (FWIW, I had upvoted your comment.) Commented Dec 7, 2011 at 18:49

6 Answers 6

9

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.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 from me for the platform knowledge we all didn't have.
6

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.

1 Comment

The fact that this was a good question is shown by the number of more or less incorrect/incomplete answers. +1 from me both to the (very good) answer and to the question (at least it's not -1 any longer!)
2

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.

1 Comment

Not very appropriate for Arduino (8-bit AVR microcontroller).
1

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());

2 Comments

I think you mean ostringstream.
@StilesCrisis: Uhm yes, of course... Working overtime messes up the brain. :)
1

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 intto 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.

Comments

0

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.

14 Comments

Of course, as a programmer this assures that you will still have a job a few years from now. But the job will be finding such stupid buffer overflows which make that phone prone to viruses, rather than writing exciting new stuff.
Why the question? I already explained that there's a buffer overflow lurking in your code. (And the question is tagged C++.)
@sbi I don't see a buffer overflow, especially since Arduino is 8 bit. I changed it to use snprintf anyway.
@StilesCrisis It does in my glibc.
@RobK 64 bits should fit, although I doubt arduino will ever be that big.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.