Pages: [1]   Go Down
Author Topic: Is there an easier way to extract a value from a string?  (Read 546 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 2
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This works:
Code:
void setup() {
  Serial.begin(115200);
    char l[] = "      <description>030 W/m2</description>";
   
    char * a = strstr(l, " W/m2");
    Serial.println (a); // prints " W/m2</description>"
    if ( a > 0 ) {
      * a = '\0';
      char * b = strstr(l, "<description>");
      Serial.println (b);  // prints "<description>030"
      strcpy (l, b + 13); // Remove the first characters, including "<description>"
      Serial.print ("..>");
      Serial.print (l);
      Serial.println ("<.."); // print "..>030<.."
      Serial.println (atoi(l)*2); // prints "60"
    }     
      l[0] = '\0'; // clear the line variable to test the next line.
}

void loop() {
}

I use it to find a value in a xml-web page. But is there an easier way to examine the line for the value?

And why does it work at all? I haven't included String.h. Because of Serial?
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19358
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just as a suggestion:

Code:
    char l[] = "      <description>030 W/m2</description>";

Don't use the variable name "l". It looks very much like one (1). In your code it is easy to confuse l and 1.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Offline Offline
Newbie
*
Karma: 2
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks!

But apart from a bad choice of variable name, it is as simple as it can be?

I am longing for a strBeween-function that I could call. That should be useful for many people. I Googled, and found that someone did it for php and c++. Can the latter be changed to compile in Arduino? The compiler complains about new and delete.


Code:
#include <iostream>
#include <cstring>

//returns substring of searchstr between delimiter1 and delimiter2
char* strbetween(char* searchstr, char* delimiter1, char* delimiter2) {
  //start of delimiter1 in searchstr
  //named betw as it contains substring to be returned
  char* betw = strstr(searchstr, delimiter1);
  //check that delimiter1 is found
  if (betw == 0) {
    return 0;
  }
  //start of delimiter2 in searchstr
  char* after_betw = strstr(searchstr, delimiter2);
  //check that delimiter2 is found
  if (after_betw == 0) {
    return 0;
  }
  //make betw point to start of substring to be returned
  betw += strlen(delimiter1);
  //check that betw is before delimiter2
  if (betw < after_betw) {
    int ret_len = after_betw - betw;
    char* ret = new char[ret_len+1];
    strncpy(ret, betw, ret_len);
    return ret;
  }
  else {
    return 0;
  }
}

void setup() {
  Serial.begin(115200);
  char* str = strbetween("Stephanie", "tep", "ie");
  Serial.println (str);
  delete[] str;
}

void loop() {
}
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3080
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am a bit concerned by your code.  If you call this function more than once,  are you likely
to be losing memory by sticking nuls in the middle of a character array ?

If you want to extract the numbers in this string,  whats wrong with starting at the beginning,
look at each character until you find a digit 0..9,   then keep reading digits until you don't have
a digit,    and each digit you get,  multiply the previous number by ten and add the most recent
digit ?
Logged

0
Offline Offline
Tesla Member
***
Karma: 148
Posts: 9753
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Using String functions, you can find the location of the first > in the string, then capture the next ~4 characters, then do the atoi function.

http://arduino.cc/en/Reference/StringObject

http://www.arduino.cc/en/Tutorial/TextString
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3080
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:

int findnum( char* s)
{
    int n ;
    int status=0 ;
    while ( *s != '\0' )
    {
        if ( *s >= '0' && *s <= '9' )
        {
             if ( status == 0 ) // first digit encountered
             {
                 n = *s - '0' ;
                 status=1 ;
             }
             else // subsequent digits
             {
                 n = (10*n)+(*s-'0') ;
             }
        }
        else
        {
             if ( status == 1 ) break ;
        }
        s++ ;
    }
    return n ;
}
Logged

0
Offline Offline
Tesla Member
***
Karma: 148
Posts: 9753
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There is a textfinder library that can search streaming strings for desired data. I think code has been posted to capture weather data from RSS feeds.

http://playground.arduino.cc/Code/TextFinder
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Temple, Texas
Offline Offline
Sr. Member
****
Karma: 14
Posts: 361
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your format is quite fixed, don't overlook this possibility:
Code:
    char s[] = "      <description>030 W/m2</description>";
    int d = atoi(s+10);  // extract integer beginning at s[10]

John
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19358
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you want some fun you can always use regular expressions:

http://www.gammon.com.au/forum/?id=11063
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 654
Posts: 50931
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am a bit concerned by your code.  If you call this function more than once,  are you likely
to be losing memory by sticking nuls in the middle of a character array ?
No. The array is static. It can contain any values and not leak memory. Memory leaks can occur only with dynamically allocated memory not being freed.
Logged

Pages: [1]   Go Up
Jump to: