Personally, I'd use a small state machine and a "consumer" approach, so you can avoid having to have a buffer for the GPS response string altogether. If you can show what one complete GPS response looks like, I could show some actual example code.
The idea is that you have one global variable, for example
static unsigned char gps_state = 0;
that tracks which logical part of the GPS response is being processed, and a function
unsigned char gps_char(const unsigned char in);
that you call for each incoming GPS response character, instead of storing it in a buffer. (You can, of course, just call it for each character in a buffer, if you have a buffer already.)
If the function returns zero, it just means the GPS response is incomplete. When the function returns nonzero, you have a complete set of numbers, for example already multiplied by 1000 (as 999,999,999 fits in an 32-bit integer, both signed and unsigned) in global variables, say
static int gps_longitude, gps_latitude;
Next call to gps_char() will reset the state, and reset those global variables (so you might need to copy them elsewhere for use).
It might sound complicated, but it is actually quite simple and compact code. Mostly, it's just that the viewpoint -- doing it via a function that consumes the GPS response one character at a time, and just occasionally tells us it has a full set of coordinates available -- is uncommon.