Search specific character in String to use as condition

I am passing some strings and some sensor data to a function.

The strings are of two types:

  1. remarks
  2. description of sensors

The remarks should be printed with Serial.println and the descriptions with Serial.print followed by the sensor data printed with Serial.println.

I have tried (String).substring() and (String).indexOf(). The character to be searched would be ':' as this would be the character that definitely differs in the two types of strings. IndexOf() seemed to give kind of a correct result in the sense that it would print the string and sensor in one line. But it would also do the same for the string without ':'.

I used at first this code:

    if ( debugName.indexOf(':') )
              Serial.print(debugName);
    else
        Serial.println(debugName);

After the result was wrong I thought that may be I would need to work with a flag which didnt improve the situation:

    if ( debugName.indexOf(':') )
        description = true;
    if ( description )
        Serial.print(debugName);
    else
        Serial.println(debugName);

Here is the whole code:

#define DEBUG_ERROR true
//#define DEBUG_ERROR_SERIAL if(DEBUG_ERROR)Serial

#define DEBUG_WARNING true
//#define DEBUG_WARNING_SERIAL if(DEBUG_WARNING)Serial

#define DEBUG_INFORMATION true
#define DEBUG_INFORMATION_SERIAL if(DEBUG_INFORMATION)Serial

const int sensor1 = 5;
const float sensor2 = 10.6;
byte previousId;

void debugTitle(const byte &id)
{
const char idTitle [] [12] = {"Time", "Lamp", "Temperature", "Humidity", "Waterlevel"};

Serial.print(F("--- "));
Serial.print(idTitle[id]);
Serial.println(F(" ---"));
}

void debugMsg(const String &debugName, const byte &id)
//template<typename T> void debug(const T &debugName, const byte &id)
{
const unsigned int debugOutputInterval = 1000;
static unsigned long debugOutputTimestamp;
unsigned long currentMillis = millis();
static bool description = false;
if (currentMillis - debugOutputTimestamp >= debugOutputInterval)
{
    debugOutputTimestamp = currentMillis;
    //static byte previousId;
    if ( id != previousId )
    {
      previousId = id;
      debugTitle(id);
    }
    if ( debugName.indexOf(':') )
        description = true;
    if ( description )
        Serial.print(debugName);
    else
        Serial.println(debugName);
}
}

template<typename T> void debugSensor(const T &debugName, const byte &id)
{
const unsigned int debugOutputInterval = 1000;
static unsigned long debugOutputTimestamp;
unsigned long currentMillis = millis();
if (currentMillis - debugOutputTimestamp >= debugOutputInterval)
{
    debugOutputTimestamp = currentMillis;
    //static byte previousId;
    if ( id != previousId )
    {
      previousId = id;
      debugTitle(id);
    }
    Serial.println(debugName);
}
}

void setup()
{
  Serial.begin(115200);
  while (!Serial);
}

void loop()
{
if ( DEBUG_ERROR )
{
    debugMsg("Hello Error: ", 1);
    debugSensor(sensor1, 1);
}
if ( DEBUG_WARNING )
{
    debugMsg("Hello Warning", 2);
    debugSensor(sensor2, 2);
}
}

Is there also a way to do the same with this function taking both strings and sensor data?

template<typename T> void debug(const T &debugName, const byte &id)

Thank you

But it would also do the same for the string without ':'.

What does indexOf() return if it does not find the String being searched for ?

UKHeliBob:
What does indexOf() return if it does not find the String being searched for ?

It returns -1

I changed the code to

if ( debugName.indexOf(':') >= 0 )

Which works.

Thank you!

Is there a way to do the same with

template<typename T> void debug(const T &debugName, const byte &id)

As this would help me to omit one function.

With indexOf() I have the following error

request for member 'indexOf' in 'debugName', which is of non-class type 'const char [14]'

You can do it via: template specialization

template<> void debug(const String& debugName, const byte &id)
{
   //Insert code only for String object here.
}

arduino_new:
You can do it via: template specialization

template<> void debug(const String& debugName, const byte &id)

{
  //Insert code only for String object here.
}

Thank you this is good to know. On the other hand in my case I still need two functions? One all data type except string and one for string?

Is there another advantage?