0
Offline
Full Member
Karma: 2
Posts: 115
Arduino rocks
|
 |
« on: February 14, 2013, 11:20:39 pm » |
String mystring = "GET /http://arduino/?page=1&time=20,40,30,2,14,2013¶m2=54& HTTP/1.1"; int a = mystring.indexOf('time'); int b = mystring.indexOf('&',a+1); Serial.println ( "substring: "+ mystring.substring(a,b) );
the above yields 'e=1' It seems to work fine is the value in indexOf is one character but blows up with a string. any info would be good. thanks.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #1 on: February 14, 2013, 11:27:35 pm » |
'time'
That isn't a string. "time"
is.
|
|
|
|
|
Logged
|
|
|
|
|
Lost Wages
Offline
Full Member
Karma: 11
Posts: 103
|
 |
« Reply #2 on: February 14, 2013, 11:57:41 pm » |
Karma bump
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Full Member
Karma: 2
Posts: 115
Arduino rocks
|
 |
« Reply #3 on: February 15, 2013, 09:56:30 am » |
thanks, that did it. I had no idea a double quote made a difference.
And thank goodness the arduino has it's own String methods. Using C string methods were a pain.
|
|
|
|
« Last Edit: February 15, 2013, 09:59:17 am by mistergreen »
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 38
Posts: 1850
|
 |
« Reply #4 on: February 15, 2013, 10:11:04 am » |
thanks, that did it. I had no idea a double quote made a difference.
And thank goodness the arduino has it's own String methods. Using C string methods were a pain.
Hopefully you don't plan on doing anything that push's the limits of the microcontrollers already limited SRAM.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6359
-
|
 |
« Reply #5 on: February 15, 2013, 10:52:15 am » |
And thank goodness the arduino has it's own String methods. Using C string methods were a pain.
The c-string equivalents need hardly any more code, and avoid you needing to use the Arduino String class and the memory-related bugs that come with it. Unless you have patched your Arduino installation to correct these bugs, the String class is currently not safe to use. Even if you do fix the bugs, storing variable length dynamic data in the heap is asking for trouble on such a memory-limited architecture.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Full Member
Karma: 2
Posts: 115
Arduino rocks
|
 |
« Reply #6 on: February 15, 2013, 12:42:25 pm » |
Oh, I didn't know the String object was such a problem.
How would I do the above code with C?
using strtr ?
My problem with the C string is converting the pointers returned into char so I can store them in a variable or array.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6359
-
|
 |
« Reply #7 on: February 15, 2013, 01:59:12 pm » |
using strtr ?
You can use strstr() to locate a string within another string, and substr() to extract part of a string into another variable. In your example, two calls to strstr() to locate the start and end of the section of interest, and one call to substr() to extract it into another buffer, would achieve the same effect as your original code. The two implementations would be pretty similar in terms of source code length and complexity.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #8 on: February 15, 2013, 03:29:39 pm » |
And thank goodness the arduino has it's own String methods. Using C string methods were a pain.
Please note that, at present, the String library has bugs as discussed here and here. In particular, the dynamic memory allocation used by the String class may fail and cause random crashes. I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.). Alternatively, install the fix described here: http://arduino.cc/forum/index.php/topic,145765
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Full Member
Karma: 2
Posts: 115
Arduino rocks
|
 |
« Reply #9 on: February 15, 2013, 07:01:29 pm » |
using strtr ?
You can use strstr() to locate a string within another string, and substr() to extract part of a string into another variable. In your example, two calls to strstr() to locate the start and end of the section of interest, and one call to substr() to extract it into another buffer, would achieve the same effect as your original code. The two implementations would be pretty similar in terms of source code length and complexity. substr() is a C++ <string> method. ANy other options?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #10 on: February 15, 2013, 07:23:54 pm » |
Maybe it's an overkill but you could use a regular expression to parse the string. Example: #include <Regexp.h>
char * mystring = "GET /http://arduino/?page=1&time=20,40,30,2,14,2013¶m2=54& HTTP/1.1";
void setup () { Serial.begin (115200); MatchState ms; ms.Target (mystring); // what to search
char result = ms.Match ("time=(%d+),(%d+),(%d+),(%d+),(%d+),(%d+)"); if (result == REGEXP_MATCHED) { char buf [10]; // to hold results int num; for (int i = 0; i < 6; i++) { Serial.print ("Result "); Serial.print (i); Serial.print (" = "); if (ms.capture [i].len < sizeof buf) { num = atoi (ms.GetCapture (buf, i)); Serial.println (num); } else Serial.println ("(too long)"); } // end for loop } // end if matched else if (result == REGEXP_NOMATCH) { Serial.println ("Did not match."); } else { Serial.println ("Error in regular expression."); } } // end of setup
void loop () { }
Output: Result 0 = 20 Result 1 = 40 Result 2 = 30 Result 3 = 2 Result 4 = 14 Result 5 = 2013
Library from: http://gammon.com.au/Arduino/Regexp.zipDocumentation: http://www.gammon.com.au/forum/?id=11063
|
|
|
|
|
Logged
|
|
|
|
|
Rome, Italy
Offline
Sr. Member
Karma: 20
Posts: 442
|
 |
« Reply #11 on: February 15, 2013, 08:02:26 pm » |
substr() is a C++ <string> method. Any other options?
The c equivalent of a string is an array of char, so when you know the start and end position of the "substring" within the larger one you can just copy the array elements into a new array. Or if you need to make a comparison you may use the 'n' variant (strncmp) which compares two strings up to a certain number of characters. I very much like the solution based on regular expressions. Mine, however, is the opposite. I see you are trying to parse the parameters of a query string. Your problem is quite specific and a less generic solution may work better in your case. Consider a loop on each character of the string. Start by locating the '?' sign, i.e. the beginning of the query string, then: 1. save the current position (+1) into a variable (e.g., name_start). From that position, start looking for the first '=' sign. The array between name_start and the position of '=' is the parameter name. 2. save the current position (+1) into a variable (e.g., value_start). From that position, start looking for the first '&' sign or space. The array between value_start and the position of '&' or space is the parameter value. 3. If you found a space exit the loop, otherwise repeat from 1. You could then make improvements to make it more robust, e.g.: manage the premature end of the query string, manage spaces or url-encoded characters, but this should give you a start.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6359
-
|
 |
« Reply #12 on: February 15, 2013, 08:04:33 pm » |
substr() is a C++ <string> method. ANy other options?
You could use strncpy().
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Full Member
Karma: 2
Posts: 115
Arduino rocks
|
 |
« Reply #13 on: February 15, 2013, 10:07:08 pm » |
For those interested, I got it to work with this SORT OF.. I used Xcode to write this (it's not fun to test on the arduino). I wish arduino uses objective C  char mystring[] = "GET /http://arduino/?page=1&time=20,40,30,2,14,2013¶m2=54 HTTP/1.1"; char temp1[40]; char temp2[40]; char *a = strstr(mystring, "time"); strncpy(temp1, a, sizeof(temp1)); char *b = strstr(temp1, "&"); strncpy(temp2, a, b-temp1); printf("%s : %s ", temp1, temp2 );
output time=20,40,30,2,14,2013¶m2=54 HTTP/1 : time=20,40,30,2,14,2013 but if I change the keyword search to 'page', I get some pointer junk at the end of the string. output page=1&time=20,40,30,2,14,2013¶m2=54 : page=1\231\333h Any ideas? Somehow convert the 'b' pointer to an integer?
|
|
|
|
« Last Edit: February 15, 2013, 10:17:40 pm by mistergreen »
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #14 on: February 15, 2013, 10:37:22 pm » |
page=1&time=20,40,30,2,14,2013¶m2=54 HTTP/1.1 is 49 characters long. Warning: No null-character is implicitly appended at the end of destination if source is longer than num (thus, in this case, destination may not be a null terminated C string).
|
|
|
|
|
Logged
|
|
|
|
|
|