Offline
Newbie
Karma: 0
Posts: 7
|
 |
« on: December 13, 2012, 07:31:44 am » |
Greetings, i am looking for a solution to reliably extract a phone number of variable length from a String. The String looks like this, with the part i need to extract being +8613920001234 : +CMGR: "REC UNREAD","+8613920001234","","12/12/13,15:08:55+50"
What i have tried so far is this quite nasty piece, which works kind of but only when specifying the length of the number i need: (sms.substring(sms.indexOf("READ\",\"")+7,sms.indexOf("READ\",\"")+21)).toCharArray(phonenumber_new,20);
I guess whats needed is to somehow extract everything between READ"," and the following ",. I would be most grateful for any insights or approaches. Peace and have a good day.
|
|
|
|
|
Logged
|
|
|
|
|
Norfolk UK
Offline
Edison Member
Karma: 23
Posts: 1320
|
 |
« Reply #1 on: December 13, 2012, 07:36:26 am » |
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #2 on: December 13, 2012, 08:33:28 am » |
Does this help Not when using a String. Which OP should not be.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 114
Posts: 2205
|
 |
« Reply #3 on: December 13, 2012, 08:38:21 am » |
Easy:
1) zero the target string; 2) search for '+' til the end of the source string; 3) from there, copy to '"', or end of the source string. 4) done.
|
|
|
|
|
Logged
|
|
|
|
|
Norfolk UK
Offline
Edison Member
Karma: 23
Posts: 1320
|
 |
« Reply #4 on: December 13, 2012, 09:03:13 am » |
Does this help Not when using a String. Which OP should not be. Ah, so String is based on string. I assumed they were different as peoples have highlighted an OP's post asking when they say string did they mean String or string.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 7
|
 |
« Reply #5 on: December 13, 2012, 09:08:48 am » |
Hi there - the current source string is a String (capital S), the one i should not be using according to PaulS :-( I'll try to follow what dhenry said, but especially the "search for '+' til the end of the source string;" is something i am not sure about how to do yet.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #6 on: December 13, 2012, 09:10:25 am » |
Ah, so String is based on string. A String object wraps a NULL terminated char array. That is not quite the same thing as being based on a string. Typically, when we ask of the OP means string or String, it is because they say one and then post some code that uses the other, or they don't post any/adequate code to make it possible to determine.
|
|
|
|
|
Logged
|
|
|
|
|
0
Online
Tesla Member
Karma: 71
Posts: 6623
Arduino rocks
|
 |
« Reply #7 on: December 13, 2012, 10:55:56 am » |
The correct way to parse those lines is to parse them!
That means you need to count ',' separators (but ignore them when inside string quotes). This will get you to the correct column, and you can extract the string-quote delimited string from there.
Unfortunately proper parsing is often quite complex (string quotes can be escaped inside a string for instance) so on a tiny little microcontroller its tempting to take shortcuts... Can come back to bite you later though.
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9401
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #8 on: December 13, 2012, 11:31:15 am » |
a quick hack to extract with 2 pointers, one to find the start and one to find the end of the string char s[] = "+CMGR: \"REC UNREAD\",\"+8613920001234\",\"\",\"12/12/13,15:08:55+50\""; // note that the \" are escaped with a \\.. char t[20];
void setup() { int len = strip(s, t); Serial.begin(9600); Serial.println("start"); Serial.println(len); Serial.print(t); }
void loop() {}
// dedicated function to strip second field which is ... not so elegant ... int strip(char * in, char * out) { char *p = in; // find start of second field while (',' != *p++); if (*p =='\"') p++; // find endpoint char *q = p+1; while ('\"' != *q++); // should also test for end of string ... first ... q--; //we know we have gone 1 byte to far int len = q - p; // warning pointer math strncpy(out, p, len); return len; }
|
|
|
|
« Last Edit: December 13, 2012, 12:15:50 pm by robtillaart »
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #9 on: December 13, 2012, 11:56:04 am » |
The out variable is never used... 
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9401
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #10 on: December 13, 2012, 12:13:36 pm » |
oops, copied too fast .... will fix it ..
... done ...
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 7
|
 |
« Reply #11 on: December 14, 2012, 10:36:47 am » |
is there any way to do what i wanted when using a String at all? I mean extract a substring of variable length from a String, not from a string[]
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #12 on: December 14, 2012, 11:03:08 am » |
is there any way to do what i wanted when using a String at all? I mean extract a substring of variable length from a String, not from a string[] Yes. The methodology is exactly the same. Find the start position. Find the end position. Extract the data in between. I recommend steel toed shoes while you shoot yourself in the foot. Less damage to your foot that way.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 50
Posts: 6546
Arduino rocks
|
 |
« Reply #13 on: December 14, 2012, 01:36:14 pm » |
Below has the various methods to slice/dice a String. What method you use depends on how the string is constructed and how consistant the data is inside the String. The number starts after the second + in the string, so that might be a start locator for capturing the number string. Probably several interesting ways to solve the issue. The substring function might be of interest. http://arduino.cc/en/Reference/StringObject+CMGR: "REC UNREAD","+8613920001234","","12/12/13,15:08:55+50" readString1 = (readString.substring(20,43));
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 71
Posts: 6824
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #14 on: December 14, 2012, 07:12:57 pm » |
As part of a larger project I'm writing a "string" object (note "object" not "class", it's all C not C++) and one of the methods extracts a field of variable length at a variable location. You just supply the delimiters. So I thought I'd plug your string into it and see if it worked. string * str; char my_char_array [100]; char * nmea = "+CMGR: \"REC UNREAD\",\"+8613920001234\",\"\",\"12/12/13,15:08:55+50\"";
str = stringCreate(100); stringLoadFromArray(str, nmea); stringGetField(str, 2, "+\"", my_char_array); printf("%s\n", my_char_array); // prints 8613920001234 It does. All of what I'm doing is for an ARM but that said this sort of function is just C so should run on anything and I plan to port it across to the Arduino one day. ______ Rob
|
|
|
|
« Last Edit: December 14, 2012, 07:27:49 pm by Graynomad »
|
Logged
|
|
|
|
|
|