Go Down

Topic: Extracting substring of variable length (Read 1 time) previous topic - next topic

overrider

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 :
Code: [Select]

+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:
Code: [Select]

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


PaulS

Quote
Does this help

Not when using a String. Which OP should not be.

dhenry

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.

Riva


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

overrider

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.

PaulS

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

MarkT

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.
[ I won't respond to messages, use the forum please ]

robtillaart

#8
Dec 13, 2012, 05:31 pm Last Edit: Dec 13, 2012, 06:15 pm by robtillaart Reason: 1
a quick hack to extract with 2 pointers, one to find the start and one to find the end of the string
Code: [Select]


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;
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

PaulS


robtillaart

oops, copied too fast .... will fix it ..

... done ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

overrider

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[]

PaulS

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

zoomkat

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"

Code: [Select]
readString1 = (readString.substring(20,43));
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

Graynomad

#14
Dec 15, 2012, 01:12 am Last Edit: Dec 15, 2012, 01:27 am by Graynomad Reason: 1
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.

Code: [Select]
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
Rob Gray aka the GRAYnomad www.robgray.com

Go Up