Please help me with sscanf

Hi, I have a sketch that I'm writing that loads up some settings from an SD card.

The settings are in a known format, comma delimited.

I tried for hours to get the %f to work to extract double values before I found out that sscanf doesn't work with %f on Arduino, so I used %s instead and just atof the result.

Well, after being up until 4am this morning trying to get it to work I have had limited success.

the output from the sample code I have listed below has the following output :

charA =17.1,28.1,20.0,13.0,18.0,10,10,10,10,5,2,10,5,0
charB =,28.1,20.0,13.0,18.0,10,10,10,10,5,2,10,5,0
charC =1,20.0,13.0,18.0,10,10,10,10,5,2,10,5,0
charD =.0,13.0,18.0,10,10,10,10,5,2,10,5,0
charE =3.0,18.0,10,10,10,10,5,2,10,5,0

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  delay(5000);
  char settingsString[73] = 
  "12:00,18:00,12:00,14:00,17.1,28.1,20.0,13.0,18.0,10,10,10,10,5,2,10,5,0";
  
        int intA, 
            intB,
            intC, 
            intD,
            intE,
            intF,
            intG,
            intH,
            intI,
            intJ,
            intK,
            intL,
            intM,
            intN,
            intO,
            intP;
            
      char  charA[4],
            charB[4],
            charC[4],
            charD[4],
            charE[4],
            charF[4];
            
     double dblA,
            dblB,
            dblC,
            dblD,
            dblE,
            dblF;
    
    sscanf(settingsString, "%d:%d,%d:%d,%d:%d,%d:%d,%s,%s,%s,%s,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d",
            &intA,
            &intB,
            &intC,
            &intD,
            &intE,
            &intF,
            &intG,
            &intH,
            &charA,
            &charB,
            &charC,
            &charD,
            &charE,
            &charF,
            &intI,
            &intJ,
            &intK,
            &intL,
            &intM,
            &intN,
            &intO,
            &intP);
            
            /*
            dblA = atof(charA);
            dblB = atof(charB);
            dblC = atof(charC);
            dblD = atof(charD);
            dblE = atof(charE);
            dblF = atof(charF);
            */
            
            Serial.print("charA ="); 
            Serial.println(charA );
            
            Serial.print("charB ="); 
            Serial.println(charB );
            
            Serial.print("charC ="); 
            Serial.println(charC );
            
            Serial.print("charD ="); 
            Serial.println(charD );
            
            Serial.print("charE ="); 
            Serial.println(charE );
}

Please could someone help me to work out what is wrong here as I'm failing miserably.

I had considered using strtok to do this but I can't get my head around that function.

Thanks in advance, Rick.

I had considered using strtok to do this but I can't get my head around that function.

Why not? It only takes two arguments?

char *token = strtok(settingsString, ":,"); // Get the first token from a string
token = strtok(NULL, ":,"); // Get the other tokens from the string

The token will be delimited properly.

Hi, thanks for the reply, I'm struggling a little with pointers at the mo but I'm getting there.

The bit that phased me was why the first param of the second call to strtok (strtok_r for arduino) is NULL.

I'm reading now about strtok, hopefully I can get an understanding of it and use it.

It's the call, call agian, call agian etc bit I'm struggling with, is there some kind of internal pointer which moves along the input string with each subsequent call when NULL is the first param?

The first call gives it the string to start scanning. It remembers where it is from then on. If you call strtok() with NULL as the first parameter it carries on from where you were after the last call.

The bit that phased me was why the first param of the second call to strtok (strtok_r for arduino) is NULL.

Do NOT use strtok_r() for the Arduino. That is the thread-safe, re-entrant version. For a non-threaded system, you don't need the overhead and complexity of a thread-safe function.

Sorted, thanks so much, I have implemented strtok successfully.

Nothing to it really, I was just getting stressed because I didn't know it would move along the string on its own :slight_smile:

So, that's great but I'm still curious to know why the sscanf code didn't work, do you have any ideas?

I would imagine because the values in your string are floating point numbers (decimal values with a fractional component), and you were using %d to parse them and store them into integers.

You would need %f and floats, but AFIAK the Arduino sscanf() doesn't have float support as it's too big.