substring from a char array

guys,
I know substring is the easiest way to find a substring:

sub_str = str_rx.substring(14);

for a set keepalive 10

Now, I am taking the thing as a char array, doing a strcmp as if (strcmp(strRS232_rx, "set keepalive ") == 0) and i need to split out the thing when it sees set keepalive 10 and to get 10. then i can hopefully do the rest. Any help plz...

int value = atoi( &strRS232_rx[14] );

... If there is always just one space. 14 is the length of the compare string, so &array [14] is a pointer to the character after that. atoi starts there, looking for digit characters.

-dev:

int value = atoi( &strRS232_rx[14] );

... If there is always just one space. 14 is the length of the compare string, so &array [14] is a pointer to the character after that. atoi starts there, looking for digit characters.

well then i have something to share mo...

this is a fixed length for different commmands... I will receive commands like set ip 10.10.10.10 or such. for each of those, I can fix it as commands are specific with the length. [14 or 12 or 20, does not matter]. So strcomp can be fixed for each command. And each command will have a space before the last parameter. Like some int value or a url or a ip... then??

(To be frank, i found another way is separating using = sign. 2 different char array using token. )

But eitherway, I need something that is efficient in terms of RAM. [else String was all okey for me]

if (strcmp(strRS232_rx, "set keepalive ") == 0)

Will only be true when both strings are equal. When and where will the "10" be held ?

UKHeliBob:

if (strcmp(strRS232_rx, "set keepalive ") == 0)

Will only be true when both strings are equal. When and where will the "10" be held ?

That i was thinking lately and thus i made that comment in (), that a seperator of = sign may help to seperate command and data/parameter.... right??

[strcmp] Will only be true when both strings are equal. [equal lemhths, too]

Ah, yes... you have to use strstr, not strcmp. Do something like

    char *ptr = strstr( strRS232_rx, "set keepalive ");
    if (ptr) {
      value = atoi ( &ptr[14] );

Or go the route of parsing out the words with strtok. Then pass the 3rd word (token) to atoi.

guys, i'm a convert from String to Char Array!! Thus not that familier with the rituals yet!!

Earlier I used substring and stripped out every IP octates. but after converting to char array, now a bit confused...

here is the code:

if (strcmp(command, "set dns") == 0) { //Set Low Temperature Limit (where compressor will go OFF)
      //sub_str = str_rx.substring(7); //earlier code
//The new IP is in variable parameter[]
      //String sub_str2 = "";
      int dotIndex = sub_str.indexOf('.');
      int secondDotIndex = sub_str.indexOf('.', dotIndex + 1);
      int thirdDotIndex = sub_str.indexOf('.', secondDotIndex + 1);
      sub_str2 = sub_str.substring(0, dotIndex);
      int ip_A = sub_str2.toInt();
      sub_str2 = sub_str.substring(dotIndex + 1, secondDotIndex);
      int ip_B = sub_str2.toInt();
      sub_str2 = sub_str.substring(secondDotIndex + 1, thirdDotIndex);
      int ip_C = sub_str2.toInt();
      sub_str2 = sub_str.substring(thirdDotIndex + 1); // To the end of the string
      int ip_D = sub_str2.toInt();

      byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("DNS set to: " + sub_str);
      NetEeprom.writeDNSConfig(ip);
      Serial.print(F(">"));
      Serial.flush();

    }

My serialParser is:

//Serial parser
void serialParser(void) {
  //
  //  One command per line.  Eventually, Data may have multiple 
  //   fields separated by ":"
  //  Command Format: "up to 5 Letter command, up to 10 letter data<\n>"
  //                  No checking.
  //
  //  count will  be below Zero on a timeout.
  //  read up to X chars or until EOT - in this case "\n" 
  byteCount = -1;
  byteCount =  Serial.readBytesUntil('\n',strRS232_rx,RS232buffSize);  
  delay(5);
  if (byteCount  > 0) {
      strcpy(command,strtok(strRS232_rx,"="));
                 
      strcpy(parameter,strtok(NULL,","));             
  }
  memset(strRS232_rx, 0, sizeof(strRS232_rx));   // Clear contents of Buffer
  Serial.flush();
}

Now as you have seen, I have separated the command and parameters (say set ip=192.168.0.10) and thus command is set ip and parameter is 192.168.0.10

now i need to save the IP in to eeprom. saving i already have done without the "." already, when i used substring. But here for this case, how can i achieve this? Please note: the IP is variable... means not always that class C... mean the position of "." may be anywhere

I am planning to get of that String out of my life as dynamic memory really made my life hell...

If you are going to use delimiters then the strtok() function will do what you want

An example

void setup()
{
  char input[] = {"ip_address=10.11.12.13"};
  char *ptr;
  Serial.begin(115200);
  ptr = strtok (input, "=");  // Look for =
  Serial.print("Command is : ");
  Serial.println(ptr);
  Serial.println();
  Serial.println("Data is : ");
  while (ptr != NULL)
  {
    ptr = strtok (NULL, ".");   // look for .
    Serial.println(ptr);
  }
}

void loop()
{
}

You can, of course, check the command and decode the data appropriately

void setup()
{
  char input[] = {"ip_address=10.11.12.13"};
  char *ptr;
  Serial.begin(115200);
  ptr = strtok (input, "=");  // Look for =
  Serial.print("Command is : ");
  Serial.println(ptr);
  Serial.println();
  if (strcmp(ptr, "ip_address") == 0)
  {
    Serial.println("Data is : ");
    while (ptr != NULL)
    {
      ptr = strtok (NULL, ".");   // look for .
      Serial.println(ptr);
    }
  }
  else
  {
    Serial.println("Unknown command");
  }
}

void loop()
{
}

Hi UKHelibob, I know it's a foolish question and yes!! yyyour given solution is exacctly doing kinda that... But Serial.println(ptr) is only printing out the things, where I need to put them in another variable.... how exactly can i do that?? More over, that while is running and I was looking for ipA, ipB, ipC, ipD [the each octates] which can be either in ip1, 2, 3, 4 or whatever...

I did this:

void setup()
{
  char input[] = {"set ip=10.11.12.13"};
  char *ptr;
  char ip[3];
  char command[25];
  char parameter[25];
  strcpy(command,strtok(input,"="));
                 
  strcpy(parameter,strtok(NULL,","));
  
  Serial.begin(9600);
  //ptr = strtok (input, "=");  // Look for =
  Serial.print("Command is : ");
  //Serial.println(ptr);
  Serial.println(command);
  Serial.println();
  Serial.print("Data: ");
  Serial.println(parameter);
  if (strcmp(command, "set ip") == 0)
  {
    Serial.println("Data is : ");

    char ip[3];

    for (int i=0; i<4; i++){
      strcpy(ip[i],strtok(parameter,"."));
    }
    
    Serial.print(ip[0]);
    Serial.print(";");
    Serial.print(ip[1]);
    Serial.print(";");
    Serial.print(ip[2]);
    Serial.print(";");
    Serial.print(ip[3]);
    Serial.println();
  }
  
  else
  {
    Serial.println("Unknown command");
  }
}

void loop()
{
}

The output is:

Command is : set ip

Data: 10.11.12.13
Data is : 
?;⸮;?;

So?????????

code update:

void setup()
{
  char input[] = {"set ip=10.11.12.13"};
  char *ptr;
  char ip[3];
  char command[25];
  char parameter[25];
  strcpy(command,strtok(input,"="));
                 
  strcpy(parameter,strtok(NULL,","));
  
  Serial.begin(9600);
  //ptr = strtok (input, "=");  // Look for =
  Serial.print("Command is : ");
  //Serial.println(ptr);
  Serial.println(command);
  Serial.println();
  Serial.print("Data: ");
  Serial.println(parameter);
  if (strcmp(command, "set ip") == 0)
  {
    Serial.println("Data is : ");

    int i = 0;
    ptr = strtok (parameter,".");
    Serial.println(ptr);
    ip[0] = ptr;
    i++;
    while (ptr != NULL)
    {
      ptr = strtok (NULL, ".");   // look for .
      Serial.println(ptr);
      ip[i] = ptr;
      i++;
    }

    Serial.print(ip[0]);
    Serial.print(";");
    Serial.print(ip[1]);
    Serial.print(";");
    Serial.print(ip[2]);
    Serial.print(";");
    Serial.print(ip[3]);
    Serial.println();
  }
  
  else
  {
    Serial.println("Unknown command");
  }
}

void loop()
{
}

Still not giving a proper output... so please show me a way so i can keep the values in different variables so that i can save it in eeprom

  Serial.print(ip[3]);A three element array has no element with the index three.

Serial.println(ptr) is only printing out the things, where I need to put them in another variable.... how exactly can i do that??

Instead of printing them save the values in a variable. An array is convenient in this case

void setup()
{
  char input[] = {"ip_address=10.11.12.13"};
  char *ptr;
  Serial.begin(115200);
  ptr = strtok (input, "=");  // Look for =
  Serial.print("Command is : ");
  Serial.println(ptr);
  Serial.println();
  if (strcmp(ptr, "ip_address") == 0)
  {
    Serial.println("Data is : ");
    byte dataArray[4];
    for (int index = 0; index < 4; index++)
    {
      ptr = strtok (NULL, ".");   // look for .
      dataArray[index] = atoi(ptr);
    }
    for (int x = 0; x < 4; x++)
    {
      Serial.println(dataArray[x]);
    }
  }
  else
  {
    Serial.println("Unknown command");
  }
}

void loop()
{
}

This program converts the number as strings to integers, puts them in the array and prints them later.

first of all, I exclusively have to use the serialparser() for stripping out command and parameter.

That part I can do, and this test, here I am also taking the same approach. With that part, actuallly I'm testing the command earlier, as based on that there will be the stripping out of IP or something else like a single digit or a another substring.

So, let's concentrate it in this way, and then I need to strip out the IP but the problem still continues. Nothing is printing out.
```
*void setup()
{
  char input[] = {"set ip=10.11.12.13"};
  char *ptr;
  char command[25];
  char parameter[25];
  byte ip[4];
  strcpy(command,strtok(input,"="));
               
  strcpy(parameter,strtok(NULL,","));
 
  Serial.begin(9600);
  //ptr = strtok (input, "=");  // Look for =
  Serial.print("Command is : ");
  //Serial.println(ptr);
  Serial.println(command);
  Serial.println();
  Serial.print("Data: ");
  Serial.println(parameter);
  if (strcmp(command, "set ip") == 0){
    Serial.println("Data is : ");

for (int i=0; i<4; i++){
      ptr = strtok (NULL, ".");  // look for .
      ip[i] = atoi(ptr);
    }
    for (int x = 0; x < 4; x++)
    {
      Serial.println(ip[x]);
    }
   
  }
 
  else
  {
    Serial.println("Unknown command");
  }
}

void loop()
{
}*
* *gives:* *
*Command is : set ip

Data: 10.11.12.13
Data is :
0
0
0
0*
```

OKKKKK....

if (strcmp(command, "set ip") == 0){
    Serial.println("Data is : ");

    ptr = strtok (parameter, ".");   // look for first .
    ip[0] = atoi(ptr);
    for (int i=1; i<4; i++){
      ptr = strtok (NULL, ".");   // look for .
      ip[i] = atoi(ptr);
    }
    for (int x = 0; x < 4; x++)
    {
      Serial.println(ip[x]);
    }
    
  }

has given it...

Do you think it's okey? :::

if (strcmp(command, "set dns") == 0) { //Set Low Temperature Limit (where compressor will go OFF)
      Serial.println("Data is : ");

      ptr = strtok (parameter, ".");   // look for first .
      ip[0] = atoi(ptr);
      for (int i=1; i<4; i++){
        ptr = strtok (NULL, ".");   // look for .
        ip[i] = atoi(ptr);
      }

      //byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("DNS set to: " + parameter);
      NetEeprom.writeDNSConfig(ip);
      Serial.print(F(">"));
      Serial.flush();

    }

Do you think it's okey? :::

Does it work ?

      Serial.println("DNS set to: " + parameter);Will not work

if (strcmp(command, "set ip") == 0) { //Set Low Temperature Limit (where compressor will go OFF)
      byte ip[4];
      ptr = strtok (parameter, ".");   // look for first .
      ip[0] = atoi(ptr);
      for (int i=1; i<4; i++){
        ptr = strtok (NULL, ".");   // look for .
        ip[i] = atoi(ptr);
      }
      //byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("IP set to: " + parameter);
      NetEeprom.writeIPConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
    }
    
    if (strcmp(command, "set subnet") == 0) { //Set Low Temperature Limit (where compressor will go OFF)
      byte ip[4];
      ptr = strtok (parameter, ".");   // look for first .
      ip[0] = atoi(ptr);
      for (int i=1; i<4; i++){
        ptr = strtok (NULL, ".");   // look for .
        ip[i] = atoi(ptr);
      }
      //byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("Subnet set to: " + parameter);
      NetEeprom.writeSubnetConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
    }

    if (strcmp(command, "set gateway") == 0) { //Set Low Temperature Limit (where compressor will go OFF)
      byte ip[4];
      ptr = strtok (parameter, ".");   // look for first .
      ip[0] = atoi(ptr);
      for (int i=1; i<4; i++){
        ptr = strtok (NULL, ".");   // look for .
        ip[i] = atoi(ptr);
      }
      //byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("Gateway set to: " + parameter);
      NetEeprom.writeGWConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
    }
    
    if (strcmp(command, "set dns") == 0) { //Set Low Temperature Limit (where compressor will go OFF)
      byte ip[4];
      ptr = strtok (parameter, ".");   // look for first .
      ip[0] = atoi(ptr);
      for (int i=1; i<4; i++){
        ptr = strtok (NULL, ".");   // look for .
        ip[i] = atoi(ptr);
      }
      //byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("DNS set to: " + parameter);
      NetEeprom.writeDNSConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
    }

and the serial parser is:

//Serial parser
void serialParser(void) {
  //
  //  One command per line.  Eventually, Data may have multiple 
  //   fields separated by ":"
  //  Command Format: "up to 5 Letter command, up to 10 letter data<\n>"
  //                  No checking.
  //
  //  count will  be below Zero on a timeout.
  //  read up to X chars or until EOT - in this case "\n" 
  byteCount = -1;
  byteCount =  Serial.readBytesUntil('\n',strRS232_rx,RS232buffSize);  
  delay(5);
  if (byteCount  > 0) {
      strcpy(command,strtok(strRS232_rx,"="));
                 
      strcpy(parameter,strtok(NULL,","));             
  }
  memset(strRS232_rx, 0, sizeof(strRS232_rx));   // Clear contents of Buffer
  Serial.flush();
}

at this stage, the parameter is holding the sub string containing IP or any other info. Now, I think that should work...

Serial.println("IP set to: " + ip[0] + "." + ip[1] "." + ip[2] "." + ip[3]);

Ok, apart from that, also another question, do I have to worry about RAM and stack and Heap?? For a prolonged operation??

[though this commands are for config mode only, will run for specific time of a life, and after which it needs reboot to take the new config in active.]

Serial.println("IP set to: " + ip[0] + "." + ip[1] "." + ip[2] "." + ip[3]);Have you actually tried this ?

There are ways to do what you want using sprintf() and you can always print the data separatly but what you tried will not work.