Sscanf with null values

I’m trying to complete comprehensive Ublox serial GPS library that is working apart from a slight issue with the NMEA data.
The NMEA format is if there is no valid data, send nothing so you end up with a load of ‘,’

This is an example of one of my data lines from the GPS:


You can see the two ,,

I have nine fields, If I use this,

sscanf(NMEAline[passLine], "VTG,%f,%c,%f,%c,%f,%c,%f,%c,%c"

Clearly things go wrong, sscanf is looking for data between the ,,

Is there a workaround or do I process the data first and ‘add’ a character between the ,,

I did try this as the RAW serial data is being received

if (gpsbuff[bufferIndex-2] == ',' && gpsbuff[bufferIndex-1] == ',') {
        gpsbuff[bufferIndex-1] = '0';gpsbuff[bufferIndex] = ',';

This does work 90% of the time but on occasions it tends to add a ‘0’ to the next and/or previous field, even if I slow the baud rate down I get the same issue.

Any suggestions would be appreciated.


Hi Paul,

maybe replace “,” with “,0,” will help you.

std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
    size_t start_pos = 0;
    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
    return str;
//rest place into main
string s = "VTG,,T,,M,0.018,N,0.033,K,D";
pc.printf("Before: %s\n", s.c_str());
pc.printf("After: %s \n", ReplaceAll(s, ",,", ",0,").c_str());

Replace function is from this source:

Br, Jan

Hi Jan,
Thanks for the quick reply :slight_smile:

I’m having trouble as always with these strings and character arrays.
What you have indicated is what I need, but I get,

Error: Use of undeclared identifier ‘ReplaceAll’

when I try your example and if I try this,

char* s;
strcpy (s, gps.NMEAline[passLine]);
pc.printf("Before: %s\n", s.c_str());

Error: Member reference base type ‘char *’ is not a structure or union

I did look at that link but couldn’t make much sense, I find most of these web examples won’t work on Mbed’s version of C or C++

My data is contained in a 2 dimension character array like this,

char NMEAline[16][128];

Any suggestions?


try code bellow and modify it for yourself

#include "mbed.h"
#include <string>

#define ROW 3
#define COL 30

char source[ROW][COL] = {"VTG,,T,,M,0.018,N,0.033,K,D", "VTG,,T,,M,0.018,,0.033,K,D", "VTG,,T,,M,0.018,N,0.033,K,"};

int main() {
    string str_temp;
    for(int x = 0; x < ROW;x++){
        printf("String from row %d: %s\n", x+1 ,source[x]);
        str_temp = "";
        for(int i = 0; i < sizeof(source[x]);i++){
            str_temp = str_temp + source[x][i];
            if(source[x][i]== ','){
                if(source[x][i+1] == ',') str_temp = str_temp + '0';
                if(source[x][i+1] == NULL) str_temp = str_temp + '0';  
        int n = str_temp.length();
        char char_array[n + 1];
        strcpy(char_array, str_temp.c_str()); 
        printf("Result of row %d: %s \n", x+1, char_array);   

BR, Jan

Hey JohnnyK,

I used your idea to do this:

// correct NMEAlines by insert ‘0’ between ‘,’
// NMEAline #0 is unused so we can copy the
// corrected data there. Then continue to copy
// next line to previous now redundant line.

int NMEAlineLength;   
for(int nm = 1; nm < line; nm++) {  // up to 16 NMEAline's  
    NMEAlineLength = strlen(NMEAline[nm]);
    int nx=0;        
    for(int n = 0; n < NMEAlineLength; n++) {  // scan NMEAline to end char
        NMEAline[nm-1][nx]=NMEAline[nm][n];   // overwrite char to previous redundant NMEAline
        if(NMEAline[nm][n]== ',' && NMEAline[nm][n+1]== ',') {  // check n and n+1 chr's for two ',,'
            NMEAline[nm-1][nx] = '0';nx++;      // add a '0' and inc nx
        NMEAline[nm-1][nx] = '\0';    // add cr/lf to end line

Spot on, perfect correction with no character drop out even with GPS update rate set to 5Hz (57600 serial baud) full NMEA data lines decoded!

Thank’s for your valuable time.