splitting part of the topic MQTT Get the relay channel

hi I am working on an MQTT project and have been stuck on a more streamline say of splitting the topic code for each relay that is sent from the MQTT broker this is what i have come up with so far but i would like to know if there is a better way to get the relay number from the topic

String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex = { 0, -1 };
int maxIndex = data.length() - 1;

for (int i = 0; i <= maxIndex && found <= index; i++) {
if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : “”;
}

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(“Message arrived [”);
Serial.print(topic);
Serial.print("] ");

String Topic = topic;

getting a splitting part of the topic looking for a more reliable way to get the relay channel

byte Relay = getValue(Topic,’/’,5).toInt();

String PubState = “/device/”+PanelID+"/control/relay/"+(String)Relay+"/State";

byte mcpIndex = (int) (Relay / 16);
byte pinOffset = Relay - mcpIndex * 16;

if(payload[0] == ‘0’){
mcps[mcpIndex].digitalWrite(pinOffset, LOW);
RelayStateArray[Relay] = 0;
client.publish(PubState.c_str(),“0”);
}
if (payload[0] == ‘1’){
mcps[mcpIndex].digitalWrite(pinOffset, HIGH);
RelayStateArray[Relay] = 1;
client.publish(PubState.c_str(),“1”);
}

but i would like to know if there is a better way to get the relay number from the topic

If you MUST use Strings, you should learn to use the String methods, like indexOf().

would you mind giving me an example of using index of in this string

What is the format of the MQTT topic?

LightuC:
What is the format of the MQTT topic?

topic = /device/"+PanelID+"/control/relay/"+RelayNumber+"/Command
message = 1 or 0 for on or off

example received via Arduino MQTT
/device/switchborad1/control/relay/1/Command
1
sent back to broker would be
/device/switchborad1/control/relay/1/State
1

kayotikz:
would you mind giving me an example of using index of in this string

String getValue(String data, char separator, int index)
{
   int sepLoc1 = data.indexOf(separator);
   if(sepLoc1 >= 0) // -1 means not found
   {
      int sepLoc2 = data.indexOf(separator, sepLoc1+1);
      if(sepLoc2 > 0)
      {
         // The first and second separators have been found. Use the characters between them...

If you don’t want to use the String class, which I highly recommend:

(Untested:)

int16_t getRelayNumberFromTopic(const char* topic)
{
	// Find "relay/" in the topic string. strstr() returns
	// a pointer to the first occurence of "relay/" in topic
	const char* pRelaySection = strstr(topic, "relay/");
	
	// If nothing is found, we need to exit here.
	if(pRelaySection == NULL)
		return -1;

	
	// pRelaySection now contains a pointer to the 'r' in 
	// "relay/". When we add 5 to the pointer, it points to 
	// the '/'. By adding 6 it will point to the character
	// after that.
	pRelaySection += 6;
	
	// Now we can copy the relay number into a separate
	// string. We need to do this, because we declared 
	// topic to be const. The buffer has to be large enough,
	// assuming a maximum of 255 relays for now.
	char strRelayNumber[4];
	
	// A maximum of 3 digits have to be copied
	uint8_t digitsCopied = 0;
	while(*pRelaySection != '/' && digitsCopied < 3)
	{
		strRelayNumber[digitsCopied++] = *pRelaySection++;
	}
	
	// We have copied all the digits between the two '/'. 
	//Now we need to append the zero terminator to the new
	//string, so it is a propper, c-string.
	strRelayNumber[digitsCopied] = '\0';
	
	// The relay number is now stored in the strRelayNumber 
	// c-string. The last thing to do is to convert it to a 
	// number and to return that number.
	int16_t relayNumber = atoi(strRelayNumber);
	
	return relayNumber;
}

LightuC:
If you don’t want to use the String class, which I highly recommend:

(Untested:)

int16_t getRelayNumberFromTopic(const char* topic)

{
// Find “relay/” in the topic string. strstr() returns
// a pointer to the first occurence of “relay/” in topic
const char* pRelaySection = strstr(topic, “relay/”);

// If nothing is found, we need to exit here.
if(pRelaySection == NULL)
	return -1;


// pRelaySection now contains a pointer to the 'r' in 
// "relay/". When we add 5 to the pointer, it points to 
// the '/'. By adding 6 it will point to the character
// after that.
pRelaySection += 6;

// Now we can copy the relay number into a separate
// string. We need to do this, because we declared 
// topic to be const. The buffer has to be large enough,
// assuming a maximum of 255 relays for now.
char strRelayNumber[4];

// A maximum of 3 digits have to be copied
uint8_t digitsCopied = 0;
while(*pRelaySection != '/' && digitsCopied < 3)
{
	strRelayNumber[digitsCopied++] = *pRelaySection++;
}

// We have copied all the digits between the two '/'. 
//Now we need to append the zero terminator to the new
//string, so it is a propper, c-string.
strRelayNumber[digitsCopied] = '\0';

// The relay number is now stored in the strRelayNumber 
// c-string. The last thing to do is to convert it to a 
// number and to return that number.
int16_t relayNumber = atoi(strRelayNumber);

return relayNumber;

}

hi LightuC
after doing some testing this code seems to work great i have to change the code from a string format to a char* and it seems to be working really well so far i would like to thank everyone for your help