Does sprintf have a maximum string format size?

Hi,

I'm writing some code to transmit tinyGPS++ parsed GPS GNGGA values (longitude, latitude, altitude etc) but I'm having problems with the sprintf function

It seems when I have a lot of format specifiers %i %s %ld, etc the function doesn't replace all the % specifiers.

For example:

int lat_int = (int)GPS_Latitude;
   int64_t lat_dec;
   
   double decimalPart = fmod(GPS_Latitude,1);
   lat_dec = decimalPart*1000000;

   int lon_int = (int)abs(GPS_Longitude);
   int64_t lon_dec;

   double decPart = fmod(GPS_Longitude,1);
   lon_dec = abs(decPart)*1000000;

  sprintf(datastring, "$$RIC,%02d:%02d:%02d,%s%i.%ld,%i", GPS_Hour, GPS_Minute, GPS_Second, (GPS_Latitude < 0 ? "-" : ""), lat_int, lat_dec, lon_int); // Puts the text in the datastring

This works up until the "lon_int" which returns "0" instead of "-2" (from the longitude coord -2.345674)

However, when I do:

   int lon_int = (int)abs(GPS_Longitude);
   int64_t lon_dec;

   double decPart = fmod(GPS_Longitude,1);
   lon_dec = abs(decPart)*1000000;

  sprintf(datastring, "%i", lon_int);

It works fine.

I tried make separate buffers (e.g datastring2 then using strcat to combine them) which works, but eventually, it seems to make the entire program unstable (by which I mean, it will stop transmitting the datastring without warning at some random point, say in 3 minutes or in 30 seconds, etc)

Does sprintf have a limited number of things it can process? Also unless I declare the lat_dec and lon_dec variables type int64 the "%ld" is replaced with a random number not remotely correct. My understanding is that a 6 digit number i.e 534688 (from the 52.534688 lat coord) should be in the int32 range? But... doesn't work using type int32.

Any ideas?

Does sprintf have a limited number of things it can process.

No. But, you will have problems is the array it is writing to is not large enough. That's why snprintf is preferred.

On the other hand, there is NO reason why you need to concatenate all the data in one string. Whatever you are sending the data to is g e t t i n g t h e d a t a o n e c h a r a c t e r a t a t i m e.

Hi,

I should have gave some background...

The reason is because it transmitting RTTY and by exactly that that way, one character at a time as high and low bits.

See here: https://ukhas.org.uk/guides:linkingarduinotontx2

This is the way it is done here aswell:

search for

sprintf(txstring, "$$$AVA,%i,%02d:%02d:%02d,%s%i.%05ld,%s%i.%05ld,%ld,%d,%i",count, hour, minute, second,lat < 0 ? "-" : "",lat_int,lat_dec,lon < 0 ? "-" : "",lon_int,lon_dec, maxalt,sats,rfm_temp);

It will look similar to mine.

A "%d" is for a 'int'
A "%ld" is for a 'long'

See: http://www.cplusplus.com/reference/cstdio/printf/.

As soon as you start to using 'uint8_t' and 'int64_t' then everything will go wrong. A single mistake in the parameters and it collapses. That is the drawback of sprintf(). Be sure to use 'int' and 'long' or make variables for the parameters or cast the parameters.

When 'int' happens to be 'int16_t' and 'long' happens to be 'int32_t', then it is still wrong to use 'int16_t' and 'int32_t', because the sprintf() expects 'int' and 'long'. To be compatible with other platforms, use 'int' and 'long'.

I think one of the links that you gave is terrible bad with the parameters. Don't do that.