strtokarduino-c++

C - How to extract integers from a mixed char array (arduino)


I am trying to extract the time from a char array, and store it into an integer (for example (092703). The char array looks like this:

"2018-09-20T09:27:03>2023-09-20T13:03:33"

I have been reading up on strtok and it seems to be what I need to use to at least break up the char array so I can deal with each individual time portion ( for example 09:27:03). I have a child strtok function there to break down each datetime period into just the time:

char * sub_pch;
    sub_pch = strtok (pch,"T");
    while (sub_pch != NULL)
    {
      printf ("Splitting sub string:\n");
      printf ("%s\n",sub_pch);
      sub_pch = strtok (NULL, " ");
    }

However the output isnt what I expetected. Perhaps I am going about this the wrong way, and I don't need to use strtok? Ive tried different solutions provided on this site but none seem to output what I need. Any advice would be greately appreciated! :) My test code is below:

#include <stdio.h>
#include <string.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S2!");



  char str[] ="2018-09-20T09:27:03>2023-09-20T13:03:33";
  char * pch;
  
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str,">");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ");
    char * sub_pch;
    sub_pch = strtok (pch,"T");
    while (sub_pch != NULL)
    {
      printf ("Splitting sub string:\n");
      printf ("%s\n",sub_pch);
      sub_pch = strtok (NULL, " ");
    }
      
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10); // this speeds up the simulation
}

**and the output is: **

Splitting string "2018-09-20T09:27:03>2023-09-20T13:03:33" into tokens: 2018-09-20T09:27:03 Splitting sub string: 2023-09-20 Splitting sub string: 13:03:33 2023-09-20

**My expected output for this code is **

2018-09-20T09:27:03 Splitting sub string: 2023-09-20 09:27:03 Splitting sub string: 2023-09-20 13:03:33

**My ideal output would be an int array with **

09:27:03, 13:03:33

Thanks for any help you can offer me.


Solution

  • Based on new information, the following may be what you are looking for.

    The always well formed string has two fields of "...Thh:mm:ss".

    The trick is to find the herald 'T', then convert the three pairs of digits to an integer.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int hmsTOint( char *p ) {
        int val = 0;
        val = strtol( p+1, &p, 10 );
        val = strtol( p+1, &p, 10 ) + val * 100;
        val = strtol( p+1, &p, 10 ) + val * 100;
        return val;
    }
    
    int main( void ) {
        char *str = "2018-09-20T09:27:03>2023-09-20T13:03:33", *p = str;
        int arr[2] = { 0 };
    
        for( int i = 0; i < 2 && (p = strchr( p+1, 'T' ) ) != NULL; i++ )
            arr[i] = hmsTOint( p );
    
        printf( "%d, %d\n", arr[0], arr[1] );
    
        return 0;
    }
    
    92703, 130333
    

    Note: although these integers "look like" the time they represent, another version would replace the value 100 in the function with 60. The numbers may look different, but will represent the time as "seconds since midnight".


    EDIT:
    If the size of the binary allows using a larger library function (that might be useful elsewhere in the program) there's also the sscanf() option.

    int hmsTOint( char *p ) {
        int h, m, s;
        if( sscanf( p+1, "%d:%d:%d", &h, &m, &s ) == 3 )
            return (h * 100 + m) * 100 + s;
    
        return 0;
    }