Decompose string

Hello,
Do you guys have some advice on how to deal with this string.
i would like to filter out int's of this (example) string:

GET /?S=0&open_hh=09&open_mm=12&submit=Enter&close_hh=&close_mm= HTTP/1.1

for example i want extract the int after open_hh=

 open_hh=09

but the index of open_hh is variable, so i need to search the string until i find 'open_hh="

my idea was something like this:

extract the value by knowing the index the = in open_hh=

stringValue = stringValue.substring(index + 2).toInt();

so i need something like

myString.startsWith("open_hh=")

but then return the index. but this function doesnt work that way.

so is there another way to do this?

Thanks in advance!

Here is a method I use to parse strings.

id fParseLIDAR_ReceivedSerial ( void * parameters )
{
  // distribute received LIDAR info
  String sTmp = "";
  sTmp.reserve ( 20 );
  String sMessage = "";
  sMessage.reserve ( StringBufferSize300 );
  for ( ;; )
  {
    EventBits_t xbit = xEventGroupWaitBits (eg, evtParseLIDAR_ReceivedSerial, pdTRUE, pdTRUE, portMAX_DELAY) ;
    xQueueReceive ( xQ_LIDAR_Display_INFO, &sMessage, QueueReceiveDelayTime );
    int commaIndex = sMessage.indexOf(',');
    sTmp.concat ( sMessage.substring(0, commaIndex) );
    sMessage.remove( 0, (commaIndex + 1) ); // chop off begining of message
    if ( sTmp == "!" )
    {
      xSemaphoreGive ( sema_LIDAR_OK );
      //  Display info from LIDAR
      sLIDAR_Display_Info = sMessage;
    }
    if ( sTmp == "$" )
    {
      xEventGroupSetBits( eg1, evtResetWatchDogVariables );
    }
    if ( sTmp == "#")
    {
      xSemaphoreTake( sema_LIDAR_Alarm, xSemaphoreTicksToWait );
      sLIDAR_Alarm_info = sMessage;
      xSemaphoreGive( sema_LIDAR_Alarm );
      xEventGroupSetBits( eg, evtfLIDAR_Alarm );
    }
    sTmp = "";
    sMessage = "";
    xSemaphoreGive( sema_ParseLIDAR_ReceivedSerial );
  }
  vTaskDelete( NULL );
} // void fParseReceivedSerial ( void * parameters )

Don't forget to do URL decoding and www+form decoding (they are not the same thing).

Check out the strtok and strstr functions that are part of the standard libc library. These are already available to you - just #include <string.h> . strstr() is probably the one you want.

I'd probably do something along the lines of this

#include <Arduino.h>
void setup();
void loop();

void setup()
{

  Serial.begin(115200 );
  while(!Serial);
  char token[] ="open_hh=";  // substring to search for
  char* ptr;  // pointer returned by strstr
  char buffer[3];  // strncpy buffer
  char str[] = "GET /?S=0&open_hh=09&open_mm=12&submit=Enter&close_hh=&close_mm= HTTP/1.1";

  ptr = strstr( str, token) + strlen( token );  // set ptr to first character after "open_hh="
  size_t len = strspn( ptr , "0123456789" );  // length of string containing just numerals
  int val = atoi( strncpy( buffer, ptr, len ) );  // extract number and convert to int
  Serial.println( val );
}

void loop() {}

it works although I suspect there's probably a better / prettier way

Thanks for pointing out the string.h lib! very usefull.

Here is my code which is use to test the function:

#include <string.h> 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {

  char str[] = "GET /?S=0&open_hh=09&open_mm=12&submit=Enter&close_hh=&close_mm= HTTP/1.1";
  char str_open_hh[2]; 
  char str_open_mm[2];
  
 char token_open_hh[] = "open_hh=";
 char token_open_mm[] = "open_mm=";

 char * open_hh;
 char * open_mm;
 

open_mm = strstr (str,token_open_mm) + strlen(token_open_mm);
strncpy (str_open_mm,open_mm,2);

open_hh = strstr (str,token_open_hh) + strlen(token_open_hh);
strncpy (str_open_hh,open_hh ,2);

Serial.println("open_hh");
Serial.println(str_open_hh);
Serial.println("open_mm");
Serial.println(str_open_mm);

delay(2000);

}

This is the result of the Serial.print:

open_mm
1209
open_hh
09

Almost there... only the result of 'open_mm' suprises me. i would suspect an output of '12' .

Any idea's why is use part of the 'open_hh' ?

Your str_open arrays are too small. You need a space in them for the null terminator as well. And you will need to set that extra char to 0.

noiasca:
what do you want to achieve in the end? Is that a part of a webserver on an UNO?

I'am trying to pull data from a webserver on an UNO.
So i have to decompose the string,which i pull with a get command, to use the values which i entered via the webserver.
so for now i want to achive that:
a string that looks like this:

"GET /?S=0&open_hh=09&open_mm=12&submit=Enter&close_hh=&close_mm= HTTP/1.1";

will be decomposed in to:

s=
open_hh=
open_mm=
close_hh=
close_mm=
and some submit buttons.

wildbill:
Your str_open arrays are too small. You need a space in them for the null terminator as well. And you will need to set that extra char to 0.

#include <string.h> 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {

  char str[] = "GET /?S=0&open_hh=09&open_mm=12&submit=Enter&close_hh=&close_mm= HTTP/1.1";
  char str_open_hh[3]; 
  char str_open_mm[3];
  
 char token_open_hh[] = "open_hh=";
 char token_open_mm[] = "open_mm=";

 char * open_hh;
 char * open_mm;
 

open_mm = strstr (str,token_open_mm) + strlen(token_open_mm);
strncpy (str_open_mm,open_mm,2);
str_open_mm[2] = '\0';  

open_hh = strstr (str,token_open_hh) + strlen(token_open_hh);
strncpy (str_open_hh,open_hh,2);
str_open_hh[2] = '\0';  

Serial.println("open_hh");
Serial.println(str_open_hh);
Serial.println("open_mm");
Serial.println(str_open_mm);

delay(2000);

}

thank you sir,

I'm still not 100% shure what you want to do, but here I have an example how to split the GET (or POST!) parameters into variables from a html form: Arduino Webserver Receive POST Data and Parameters

Here is my take on what you are trying to do

void setup()
{
  Serial.begin(115200);
  char str[] = "GET /?S=0&open_hh=09&open_mm=12&submit=Enter&close_hh=&close_mm= HTTP/1.1";
  char * ignore = strtok(str, "=");
  ignore = strtok(NULL, "=");
  char * open_hh = strtok(NULL, "&");
  Serial.print("extracted open_hh = ");
  Serial.println(open_hh);
  ignore = strtok(NULL, "=");
  char * open_mm = strtok(NULL, "&");
  Serial.print("extracted open_mm = ");
  Serial.println(open_mm);
}

void loop()
{
}

If you want actual integers you can convert the strings using the atoi() function