Just a quick question about passing char arrays to functions.
I just want to confirm Ive read the reference and docs properly.
Can anyone confirm that you cant pass a char array to a function except via reference (char*)?
Also can you return a char array from a function or do you have to include the array you want to return through a referenced array in the parameters? so I cant do:
Gordon, in C and C++ you cannot pass arrays to functions as parameters, nor return them from functions. There are several options for getting around this, however. As you mentioned, you can pass a pointer to the array or return a pointer (or reference) from the function. You can also wrap the array in a struct or class to return it.
If your goal is to write a function that "returns" static strings like the one in your example, it is perfectly reasonable to write
char *myFunction()
{
return "returnedText"; // this returns a pointer to the string, not the string itself
}
char *str = myFunction();
Serial.println(str); // prints "returnedText"
Gordon, I'd like to spend a minute explaining why this won't work either, even though it compiles correctly.
char string[5]; // declare a 5-character array
myFunction( string ); // create a pointer to the first char in string and pass the pointer to myFunction
void myFunction( char* localString){
// At this point localString is a 16-bit pointer variable containing the address of string. It "points" to string.
// The following line changes localString so that now it points somewhere else: to the string "abcde"
// Note that it DOESN'T change the contest of "string" in any way. All it does is point localString elsewhere.
localString = "abcde";
// myFunction exits: nothing has been done.
}
If you want "string" to be filled up with the string "abcde" you need to do two things. First modify myFunction so that it actually copies the string into "string":
Sorry the examples were simple semi pseudo code written from memory and not checked and compiled. I understand the 0 end character for the string array.
There wont be any static strings in the final functions.
My aim is to write some functions to parse xml retrieved by the Ethernet shield and libraries. What Im trying to write is a function that accepts 2 parameters, the start and end tags wrapped around the text I want, and returns the text between.
for example Title.
Id liked to have written :
char title[] = getText( "", "");
Where the function getText() steps through the xml returned by the ethernet libraries
and returns the string "Title". Ive no problem with the processing the xml or the ethernet libraries. Its just the best way of passing the parameters and returning the results.
I think combining what you've both replied with is what Ill have to do.
char startTag = "";
char endTag = "";
char text[50]; //being vary careful later to make sure there's no overflow
getText( startTag, endTag, text);
void getText( char* localStartTag, char* localEndTag, char* localText){
/*
Take the start and end tags and find the text
The ethernet library results are returned one character at a time
When I find the text I put each character into localText till its full with a "0" at the end
*/
}
I think Im explaining it clearly, does it make sense?
Your explanation is very clear, and I think you understand what needs to happen. Does your getText function actually read from the XML stream directly? I would assume so.
To be perfectly safe, you might add a "size" parameter so that getText knows how big the available buffer space is. Something like
void getText(char *localStartTag, char *localEndTag, char *resultingInnerText, int buffer_size)
{...}
Yes, it reads the stream a single character at a time as this is how the ethernet library passes the response from the web server. I then build it up into a variable the same size as the tag and keep rolling through it till I find a matching tag. That way I use as little ram on the Arduino as possible.
Its a pity the ethernet shield hasnt enough memory to hold the whole response and allow you to move around it as you like. Ive looked through the specs and libraries and unless if missed something theres only a 16k buffer. So Im stuck with a single walk through the response unless I make another request and start at the top again.
I was going to simply check the size of the referenced array rather than pass the size to the function.
getText("", "", text, 50);
Can I really do that, passing the strings as a reference?
I thought I would have to pass variables rather than the string literals.
So the location of the string literals are passed. That ties up with what Ive read that strings like this are copied from program space to ram.
Im getting there.
All my previous programming hasnt been this restricted since using a ZX81.
Ive got too used to big web servers, lots of storage and ram.
"There is no way to determine the size of the text buffer inside the getText() function, because all you have is a pointer to the first element."
That explains why a bit of code I was experimenting with didnt do what I expected.
Maybe iterating through each character till I hit the 0 end of string marker would do
Ill decide if its worth the hassle/program memory.
Once Ive finished this Ill post it up.
It may be useful to someone. I work slow so dont hold your breath.
I have to wait till health and family commitments allow me some time and energy to work.
Maybe iterating through each character till I hit the 0 end of string marker would do.
This is a good general technique, but remember that in this case you are not passing a string with a terminating 0, but a buffer with unknown contents. The size you want is the physical size of the buffer, not the length of its contents. There really is no way of calculating this value at either compile or run time. If you want the size, you will have to either pass it in to getText or make some assumptions about it.