correct use of sscanf

Hello I am trying to parse NMEA data to string and float variables using sscanf. Unfortunately it does not work as planned. All variables remain emtpy....
Does anybody know how to correctly apply sscanf with the arduino ide?

Here's the code:

 #include "WString.h"
String line = "$GPRMC,210508.000,A,4940.1220,N,00759.4077,E,1.12,2.87,101109,,*0D";
float groundSpeed, heading;
String datum;
void setup(){
  
  datum = "";
  sscanf (line,"%*s,%*s,%*s,%*s,%*s,%*s,%*s,%f,%f, %s, %*s,  %*s",&groundSpeed, &heading, &datum);

Serial.begin(4800);
Serial.print("groundSpeed: ");
Serial.println(groundSpeed);
Serial.print("heading: ");
Serial.println(heading);
Serial.print("datum: ");
Serial.println(datum);
}
void loop(){
}

It doesn't even compile as planned.
You've got "groundspeed" and "groundSpeed"

Hello I am trying to parse NMEA data to string and float variables using sscanf.

If your goal is to use NMEA data in a sketch then have a look at the excellent TinyGps library : TinyGPS | Arduiniana

If your goal is to understand how to parse NMEA data on the Arduino platform then studying the TinyGPS source code is a good place to start. sscanf needs a string buffer but Arduino does not have much RAM, so parsing the data stream character by character as in TinyGPS is much more efficient.

The sscanf call has %*s in the format string, which is not valid. It's not surprising that the result is nothing in the specified variable.

%s is used to parse a string from the input, which you are then trying to store in a float. You need to use %f to get a float value from the string.

The sscanf call has %*s in the format string, which is not valid

Not valid on the Arduino implementation, or not valid ever?
My reference has it that %s simply consumes anything unwanted, described as "An optional assignement-suppressing character ''"

Oops. My mistake. You are correct. The %*s means to read and discard the string up to the first comma.

Seems like the problem lies in the comma separators. When I replace the commas with whitespaces, everything seems to work.

Strange though...

I'd like to re-open this "correct use of sscanf" topic, because a search for "sscanf arduino" sent me to this thread.

Using sscanf for types float and double is still not working for me. Bug or my mis-use?

#include <stdio.h>
long lng, lng2;
double dpp;
float flt;
int r1, r2, r3;
void setup(){
  
  r1 = sscanf ("123.45", "%f", &dpp);
  r2 = sscanf ("123.45", "%f", &flt);
  r3 = sscanf ("123.45", "%d.%d", &lng, &lng2);

  Serial.begin(9600);
  delay(3000); // time to get the terminal running
  Serial.print("sscanf() to a double returns: ");
  Serial.print(r1);
  Serial.print(", yeilds: ");
  Serial.println((long)(dpp*100));
  Serial.print("sscanf() to a float, returns: ");
  Serial.print(r2);
  Serial.print(", yeilds: ");
  Serial.println((long)(flt*100));
  Serial.print("(a hack) sscanf() to two longs, returns: ");
  Serial.println(r3);
  Serial.print("and yeilds: ");
  Serial.print(lng);
  Serial.print(".");
  Serial.println(lng2);
}
void loop(){
}

Tell me if sscanf to a float works for you (and where did I go wrong?)!
Also if there are alternatives that convert text to float, that might help.

Tell me if sscanf to a float works for you

It did not.

(and where did I go wrong?)!

I can't see anything wrong with the call. It is possible sscanf does not support floating-point numbers.

Also if there are alternatives that convert text to float, that might help.

These two worked for me...

  f2 = [glow]atof[/glow]( "123.45" );
  f3 = [glow]strtod[/glow]( "54.321", &end );

Thanks CB, I think that you are right - that floats are not supported, Good to know (and thanks for the alternatives :)!!

When in doubt, I guess one could always read the documentation :wink:

The %s format in sscanf is defined to read a string until it encounters white space. If you want it to stop on a comma, you should use the %[^,] format.

The avr_libc documentation (avr-libc: AVR Libc) says that floating point support is optional. It sounds like the Arduino libraries do not include that option.

Personally, if I were parsing this string, I would use strtok(). In general, I don't recommend the use of sscanf() or any of its kin.

Regards,

-Mike