Read first characters from byte array

I am using the following sketch - courtesy of Nick Gammon, to read GPS data on the Serial port.
I do not wish to use String functions, but stay with byte arrays.
The GPS device sends the complete NMEA strings.
I would like to only read the "$GNRMC" data.
How do I filter out only the data that starts with "$GNRMC"?

The sketch:

/*
Example of processing incoming serial data without blocking.

Author:   Nick Gammon
Date:     13 November 2011. 
Modified: 31 August 2013.

Released for public use.
*/

// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 1024;

void setup ()
  {
  Serial.begin (9600);
  } // end of setup

// here to process incoming serial data after a terminator received
void process_data (const char * data)
  {
  // for now just display it
  // (but you could compare it to some value, convert to an integer, etc.)
  Serial.println (data);
  }  // end of process_data
  
void processIncomingByte (const byte inByte)
  {
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte
      
      // terminator reached! process input_line here ...
      process_data (input_line);
      
      // reset buffer for next time
      input_pos = 0;  
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch
   
  } // end of processIncomingByte  

void loop()
  {
  // if serial data available, process it
  while (Serial.available () > 0)
    processIncomingByte (Serial.read ());
    
  // do other stuff here like testing digital input (button presses) ...

  }  // end of loop

How do I filter out only the data that starts with "$GNRMC"?

The GPS unit may well have a way of being configured only to send that message.

To answer your question if you cannot set it up that way, once the message is in the data variable it is printed. If you only want to print the $GNRMC messages then before printing it you could check whether the data variable contains that string using the strstr() function and only print data if the string is matched.

you can try it this way, using @UKHeliBob's advice but with a new function to parse the information:

const size_t MAX_MESSAGE_LENGTH = 128;

template <class T> inline Print& operator <<(Print& obj, T arg)
{
  obj.print(arg);
  return obj;
}

void setup() 
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  Serial << (F("let's go!\n"));
}

void loop() 
{
  if(const char* newMessage = checkForNewMessage(Serial, '\n'))
  {
    if (strstr(newMessage, "$GNRMC")) {
      Serial << (F("Got GNRMC Message!\n"));
      Serial << (F("Just Recieved:\t")) << newMessage << (F("\n"));
    }
  }
}

const char* checkForNewMessage(Stream& stream, const char endMarker)
{
  static char incomingMessage[MAX_MESSAGE_LENGTH] = "";
  static byte idx = 0;
  if(stream.available())
  {
    incomingMessage[idx] = stream.read();
    if(incomingMessage[idx] == endMarker)
    {
      incomingMessage[idx] = '\0';
      idx = 0;
      return incomingMessage;
    }
    else
    {
      idx++;
      if(idx > MAX_MESSAGE_LENGTH - 1)
      {
        //stream.print(F("{\"error\":\"message too long\"}\n"));  //you can send an error to sender here
        idx = 0;
        incomingMessage[idx] = '\0';
      }
    }
  }
  return nullptr;
}

I do not wish to use String functions, but stay with byte arrays.

But you don't have any byte arrays. You have char arrays.

You have a lot of inconsistencies in your code, though. You store bytes in char arrays. NOT a good thing, since byte is unsigned, while char is signed, so they do not hold the same range of values. You are getting away with it because the GPS sends chars, not bytes, so all the values fit in a byte or a char, but you really should fix the code to be consistent.

You can use strncmp() to tell if the first n characters of one string match the first n characters of another string, like "$GNRMC".

No need to over-complicate stuff by using templates or <<.