New Jersey
Offline
Sr. Member
Karma: 0
Posts: 356
|
 |
« on: August 26, 2012, 12:46:15 pm » |
I'm passing a character array to a function, and I can get it to work two different ways. I'm wondering if one is preferred over the other. Method 1 char msg[] = "Hello World"; SendMsg(msg);
Method 2 SendMsg("Hello World");
SendMsg function void SendMsg(char myMsg[]) { char MsgAndTime[strlen(myMsg) + 10]; strcpy(MsgAndTime, myMsg); strcat(MsgAndTime, " 1:00 PM"); Serial.println(MsgAndTime); }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Faraday Member
Karma: 16
Posts: 3196
20 LEDs are enough
|
 |
« Reply #1 on: August 26, 2012, 01:27:50 pm » |
It depends on what else you are doing. But IMHO concatenating two strings for output is a bad idea. Better output the two strings separately thus avoiding unnecessary use of RAM. Also: if you are using string constants you should learn about progmem.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 316
Posts: 35593
Seattle, WA USA
|
 |
« Reply #2 on: August 26, 2012, 02:36:37 pm » |
I second what Udo says. The data being sent to the serial port by: char MsgAndTime[strlen(myMsg) + 10]; strcpy(MsgAndTime, myMsg); strcat(MsgAndTime, " 1:00 PM"); Serial.println(MsgAndTime); and Serial.print(myMsg); Serial.println(" 1:00 PM"); is exactly the same, and the receiving end will have no idea which method was used. The second uses less memory, is faster, and is far less likely to have issues with overwriting array bounds (if you change the size of the string concatenated, without changing the array size).
|
|
|
|
|
Logged
|
|
|
|
|
New Jersey
Offline
Sr. Member
Karma: 0
Posts: 356
|
 |
« Reply #3 on: August 26, 2012, 07:16:49 pm » |
It depends on what else you are doing. But IMHO concatenating two strings for output is a bad idea. Better output the two strings separately thus avoiding unnecessary use of RAM. Also: if you are using string constants you should learn about progmem.
I need to concatenate the two strings together because the message is going out to Twitter. In the Tweet I want to have the message and a timestamp. If twitter sees two identical tweets one after the other it will just drop the 2nd one. The timestamp prevents this. I know I could just put millis() or something instead of the time, but that wouldn't change the need to concatenate two strings.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Faraday Member
Karma: 16
Posts: 3196
20 LEDs are enough
|
 |
« Reply #4 on: August 27, 2012, 12:28:46 pm » |
@ScottG: as PaulS confirmed the receiving end will never know that the strings were not concatenated. It does not matter if the receiving end is sending twitter messages or something else. It will never notice the difference.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6415
-
|
 |
« Reply #5 on: August 27, 2012, 01:27:23 pm » |
I need to concatenate the two strings together because the message is going out to Twitter.
No you don't. What goes over the serial port is identical in both cases; all that's changing is the code you use to put that sequence of characters into the transmit buffer.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 316
Posts: 35593
Seattle, WA USA
|
 |
« Reply #6 on: August 28, 2012, 05:10:55 am » |
No you don't. What goes over the serial port is identical in both cases; all that's changing is the code you use to put that sequence of characters into the transmit buffer. Actually, OP does. The twitting library has one method to post a twit, and that method takes a string.
|
|
|
|
|
Logged
|
|
|
|
|
New Jersey
Offline
Sr. Member
Karma: 0
Posts: 356
|
 |
« Reply #7 on: September 07, 2012, 07:19:00 am » |
If I pass a character array to a function, then add to it by using strcat() will my program adjust the memory allocated for this char array, or am I going to run into a memory problem. For example void createMsg() { char msgTweet[27]; strcpy(msgTweet, "This is 26 characters long"); sendMsg(msgTweet); }
void sendMsg(char msgToSend[]){ char addToMsg[] = "stuff";
// add stuff to the message strcat(msgToSend, addToMsg); Serial.println(msgToSend); }
|
|
|
|
|
Logged
|
|
|
|
|
Ayer, Massachusetts, USA
Offline
Edison Member
Karma: 28
Posts: 1115
|
 |
« Reply #8 on: September 07, 2012, 07:23:23 am » |
If I pass a character array to a function, then add to it by using strcat() will my program adjust the memory allocated for this char array, or am I going to run into a memory problem.
You are going to run into problems and overwrite whatever happens to be adjacent to your array. Strcat is fairly low level, and it assumes you have already checked that there is enough space allocated in the array to hold the current string plus the new string and the trailing byte. There is the String class that does what you want, but since it uses dynamic memory allocation, it is subject to running out of memory. I tend to be of the opinion that in a memory poor environment like the Arduino you should never use dynamic allocation (or if you must, only use it very sparingly).
|
|
|
|
|
Logged
|
|
|
|
|
New Hampshire
Offline
God Member
Karma: 13
Posts: 776
There are 10 kinds of people, those who know binary, and those who don't.
|
 |
« Reply #9 on: September 07, 2012, 07:35:58 am » |
If I pass a character array to a function, then add to it by using strcat() will my program adjust the memory allocated for this char array, or am I going to run into a memory problem. For example
strlcat() can be used to prevent writing outside the bounds of the destination buffer. It will just truncate the second string if necessary. Here is the reference for all the C string library functions: http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html#ga1fd2a6e188f02599e5eeb17519f67f3e
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 2
Posts: 212
|
 |
« Reply #10 on: September 07, 2012, 08:14:29 am » |
please try to adjust your sendmsg function like this, i believe it should work. void SendMsg(char * myMsg) // << points to your array and that should be enough, a basic c++ method { char MsgAndTime[strlen(myMsg) + 10]; strcpy(MsgAndTime, myMsg); strcat(MsgAndTime, " 1:00 PM"); Serial.println(MsgAndTime); }
notice only the main calling method is changed the way you would if calling for an array function variable. if it doesnt work then arduino isnt c++ compliant but i dont doubt it wouldnt work like this.
|
|
|
|
« Last Edit: September 07, 2012, 08:18:41 am by PGTBOOS »
|
Logged
|
|
|
|
|
New Jersey
Offline
Sr. Member
Karma: 0
Posts: 356
|
 |
« Reply #11 on: September 07, 2012, 10:00:24 am » |
please try to adjust your sendmsg function like this, i believe it should work. void SendMsg(char * myMsg) // << points to your array and that should be enough, a basic c++ method { char MsgAndTime[strlen(myMsg) + 10]; strcpy(MsgAndTime, myMsg); strcat(MsgAndTime, " 1:00 PM"); Serial.println(MsgAndTime); }
notice only the main calling method is changed the way you would if calling for an array function variable. if it doesnt work then arduino isnt c++ compliant but i dont doubt it wouldnt work like this. That was pretty much my plan B. But I was going to use (no pointer like in your example ): void SendMsg(char myMsg) I have a hard time grasping pointers. I understand how they work, but it's much less intuitive and harder to understand for me. I thought when you passed an array to a function, C always passes it as pointer. Is that right? So what's the difference between these two functions: void SendMsg(char myMsg) void SendMsg(char * myMsg)
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Edison Member
Karma: 27
Posts: 1510
|
 |
« Reply #12 on: September 07, 2012, 10:27:30 am » |
So what's the difference between these two functions: void SendMsg(char [ ] myMsg) void SendMsg(char * myMsg) None. Inside SendMsg you don't know the size of myMsg, just the strlen. And you can use both the same way: e.g. myMsg[i] *(myMsg+i) are identical and valid in both cases
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 31
Posts: 2947
I only know some basic electricity....
|
 |
« Reply #13 on: September 07, 2012, 04:45:13 pm » |
void SendMsg(char myMsg)
Passes SendMsg a signed 8-bit value. void SendMsg(char * myMsg)
Passes SendMsg an unsigned 16-bit address to a signed 8-bit value. Using the address (pointer) you can access that char, and others by their relative memory positions. IMO best practice would be to make the original array big enough to hold the time stamp -- if you have to print just one string -- then strcat to that. You might check but perhaps the twit thing looks for a newline or carriage return to determine end of message rather than timing out serial chars received or however it's supposed to "know" one bunch of print chars from the next -- you can fill the transmit buffer WAY faster than it sends chars out.
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Offline
Edison Member
Karma: 15
Posts: 1009
Arduino rocks
|
 |
« Reply #14 on: September 07, 2012, 08:03:03 pm » |
sendMsg needs to take a const char* argument.
|
|
|
|
|
Logged
|
|
|
|
|
|