How to remove a set of chars from my variable char array

Greetings,

I have a string of chars that I get from a GPRS unit. However, the new LTE unit I have does not simply return all the chars in one fell swoop. It returns them with a pesky "+HTTPREAD: 1024" every 1024B. The number 1024 is variable.

I am trying to remove these. Here are the chars returned, however, to start with, I have replaced the CRLF's with a PIPE symbol:

+HTTPREAD: 1024||^A#0000040~00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666600066600006666600066666600000000000000000000000000000000000000666666606666666006666600666666000000000000000000000000000000000000000006660066066000660660006606600066000000000000000000000000000000000000006600066066000660660006606600066000000000000000000000000000000000000000066000660660006606600066066000660000000000000000000000000000000000000066666600660006606666666066000660000000000000000000000000000000000000000660006606666666066000660006666600000000000000000000000000000000000000660066006600066066000660660006600000000000000000000000000000000000000006600066066000660660006606600066000000000000000000000000000000000000006600066066000660660006606600666000000000000000000000000000000000000000006666660660006606666666066000660000000000000000000000000000000000000066000660066666||+HTTPREAD: 1024||0066000660666660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066000066006666600666666006600066006666660000000000000000000000000000006666666066000660666666606666666066000066000000000000000000000000000000660000660660006606600066066000660660000000000000000000000000000000000000000660066006606600066066000660660000660000000000000000000000000000006600006606600066066000660660660006600000000000000000000000000000000000066666600006666006666660660006606606606600000000000000000000000000000066066066066000660666660006666000006666660000000000000000000000000000006600000000660660066006606600066066066066000000000000000000000000000000666666660660006606600066066006600000006600000000000000000000000000000066000000660006606600066066000660666666660000000000000000000000000000006660066606666666066000660660006606666666000000000000000000000000000000066666606600066066000660066666006600006600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000||+HTTPREAD: 1024||0000000000066666000666000666666606600066000666000000000000000000000000000000000666660066000660666666600666660066666600000000000000000000000000000000066600660660006600000066066000660660006600000000000000000000000000000066000660660006606600000066000660660006600000000000000000000000000000000660006606600066000000660660006606600066000000000000000000000000000000666666606666666066666660666666606600066000000000000000000000000000000006600066066666660666666606666666066666660000000000000000000000000000006600066066000660660000006600066066000660000000000000000000000000000000066000660660006600000066066000660660006600000000000000000000000000000066000660660006606600000066000660660066600000000000000000000000000000000066666606600066066666660660006606600066000000000000000000000000000000660006606600066066666660660006606666600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000||+HTTPREAD: 20||0000000000000000000=||+HTTPREAD: 0|

What I am trying to do is to iterate through the above char array, (which is declared as char leds[NUMLEDS]) and copy only the non-HTTPREAD chars to a new ledsbuf array. I do not want any of the pipe symbols nor the HTTPREAD: 1024 or whatever the number other than 1024 may be.

I am using the ATMEGA1284P chip by the way.

Here is my code, it seems to be stuck in an infinite loop:

char * ret = strstr(leds, "+HTTPREAD:"); //find the first HTTPREAD:
      ret = strstr(ret, "||") + 2; //go past the first ||

      //loop thru all to find http and ||
      memset(ledsbuf, 0, NUMLEDS);
      while (ret)
      {
        char * endret  = strstr(ret, "||+HTTPREAD:");
        int idxend = endret - ret;
        strncat(ledsbuf, ret, idxend);
        ret = ret + 10; //move away from the current HTTPREAD
        ret = strstr(ret, "+HTTPREAD:"); //move to next HTTPREAD
        ret = strstr(ret, "||") + 2; //move to next || plus 2
      }
      if (showDebugData)  //at the mo I never get here...
      {
        Serial.print("PIPE:"); Serial.println((char*)ledsbuf);
      }

So what am I doing wrong?

That loops until (ret) is not true. When will it ever be not true?

When strstr() does not find the string it returns a null pointer.

Then, perhaps the infinite loop is NOT in your snippet.

Indeed!!!

This works fab, thanks!

bool firstloop = true;

      while (ret)
      {
        char * endret  = strstr(ret, "||+HTTPREAD:");
        if (endret == NULL) break; //trap the EOF not having an end index
        if (!firstloop) ret = ret + 2;  //dont move 2 places during the first iteration
        firstloop = false;
        int idxend = endret - ret;
        strncat(ledsbuf, ret, idxend);
        ret = ret + 5; //move away from the current HTTPREAD
        ret = strstr(ret, "+HTTPREAD:"); //move to next HTTPREAD
        ret = strstr(ret, "||"); //move to next ||
      }

Hi Delta_G

Yes that is an excellent solution! Why the HELL didnt I think of that?

I'll try that tomorrow. Much obliged!

Here is Delta_G's much more elegant solution which works just fab!

memset(ledsbuf, 0, NUMLEDS);
      char * ret = strstr(leds, "||+HTTPREAD:"); //find the first HTTPREAD:
      const char s[3] = "||";
      char *token;
      /* get the first token */
      token = strtok(ret, s);
      /* walk through other tokens */
      while ( token != NULL )
      {
        if (strstr(token, "HTTP") == NULL)
        {
          strcat(ledsbuf, token);
        }
        token = strtok(NULL, s);
      }