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.
B-D-N
October 9, 2020, 1:23am
4
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