102. Parse GPS String for Time and Coordinates

You are given a $GPRMC NMEA string from a GPS module in the following simplified format:

$GPRMC,<time>,<status>,<lat>,<NS>,<long>,<EW>,...

Your task is to:

  • Extract and print:
     
    • UTC time in HH:MM:SS format (first field after $GPRMC)
    • Latitude with direction (lat NS) : NS- North South
    • Longitude with direction (long EW) : EW- East West

Assume:

  • Input will always follow this format
  • You only need to extract and print the first 7 fields
  • Do not validate checksum or GPS fix status
     

Example-1

Input:
$GPRMC,123519,A,4807.038,N,01131.000,E
Output:
Time: 12:35:19  
Latitude: 4807.038 N  
Longitude: 01131.000 E


Example-2

Input:
$GPRMC,083559,A,3745.678,N,12227.890,W
Output:
Time: 08:35:59  
Latitude: 3745.678 N  
Longitude: 12227.890 W


 

Need Help? Refer to the Quick Guide below

What Is a String in C?

A string in C is an array of characters terminated by a null character ('\0').

char msg[ ] = "OK";  // Stored as: ['O', 'K', '\0']
  • Strings are not a built-in type in C
  • No bounds checking is done by default
  • Handled as raw character arrays
     

 How Are Strings Stored in Memory?

char s[ ] = "Hi";

Index:   0     1     2
Value: 'H'   'i'   '\0'

You must always account for the null terminator when allocating space.

char name[10]; // Can store 9 characters + '\0'

 

Common String Operations (In Firmware Style)

OperationDescription
strlen()Count length (excluding '\0')
strcpy()Copy string
strcmp()Compare two strings
strchr()Search for a character
strcat()Concatenate (⚠️ risky — can cause overrun!)
atoi() / strtol()Convert string to integer

In firmware, we often reimplement minimal-safe versions of these.

 

Character Classification

Useful when parsing commands, serial input, file systems, etc.

CheckFunctionASCII Range
Is digit?isdigit(c)'0' to '9'
Is alpha?isalpha(c)'A'–'Z', 'a'–'z'
Is alphanumeric?isalnum(c)Digit or alpha
To upper/lowertoupper(c), tolower(c)Changes case

You can implement these yourself using ASCII values.

Example: Custom isdigit() Implementation

int is_digit(char c) {
    return (c >= '0' && c <= '9');
}

Parsing Input Strings (Firmware Use Cases)

Firmware often receives comma-separated or command-style input via UART or SPI:

char input[ ] = "SET,12,ON";

You may need to:

  • Split string on delimiter (e.g., ',')
  • Convert fields to numbers
  • Validate content (only ASCII allowed?)
     

Use functions like:

  • strtok() (not always safe)
  • Manual scanning with a for loop
     

Common String Challenges in Firmware

ProblemExample / Notes
Null terminator missingCauses garbage output, memory overread
Buffer overflow in strcpy()Common cause of firmware bugs
Unsafe use of strcat()Overwrites adjacent memory
Improper parsingFails if input format changes
Memory-inefficient operationsPrefer minimal parsing logic

 

Embedded Relevance

  • Parsing GPS/NMEA strings
  • Processing AT commands in modems
  • Reading sensor configuration strings
  • Displaying values on LCD/UART
  • Data logging & debugging
     

Best Practices for Embedded C

  • Always limit copy lengths (strncpy, or manual copy with bounds)
  • Avoid dynamic memory (malloc, strdup) — use static arrays
  • Validate each character when parsing input
  • Handle all strings as byte buffers, especially in communication protocols
     

Common Pitfalls (Practical Tips)

PitfallWhat to Do
❌ Forgetting '\0' terminatorAlways allocate +1 byte for strings
❌ Using strcpy blindlyPrefer safer copy functions with limit
✅ Use sizeof(arr) wiselyOnly works for stack arrays, not pointers
✅ Parse manually for safetyAvoid strtok() if reliability matters
✅ Reuse char arrays where possibleMinimize static memory usage