Arduino - sscanf()

Hello everyone,

I'm trying to use the sscanf() function to obtain some variable values from a SD card text.
This is a snnipet of what I'm trying to do.

char *data = "[08:30:15]1.2.3.4=99";
int hour = 0;
int minute = 0;
int number = 0;
char string[16];

void setup() {
  Serial.begin(115200);
  Serial.println("\nInitializing");
  Serial.println(data);
  sscanf(data, "[%02d:%02d:%*d]%15s=%02d", hour, minute, string, number);
  Serial.println(hour);
  Serial.println(minute);
  Serial.println(string);
  Serial.println(number);
}

    
void loop() {}

But here is what I got from the Serial Monitor.

Initializing
[08:30:15]1.2.3.4=99
0
0
1.2.3.4=99
0

I'm using this as reference, if anyone can take a look.

sscanf()
printf()

Thanks in advance.

sscanf(data, "[%02d:%02d:%*d]%15s=%02d", &hour, &minute, string, &number);

Also looks like you've got too many formats, not enough variables.

That site you linked looks rubbish.

AWOL:

sscanf(data, "[%02d:%02d:%*d]%15s=%02d", &hour, &minute, string, &number);

Thanks AWOL, it seens to work better, but still with a problem on the last variable.

AWOL:
Also looks like you've got too many formats, not enough variables.

The "%*d" format shouldn't discard that value?

Anyway, I added another variable to hold that value, but the last one, the "number" still don't work, do you know why?

char *data = "[08:30:15]1.2.3.4=99";
int hour = 0;
int minute = 0;
int second = 0;
int number = 0;
char string[16];

void setup() {
  Serial.begin(115200);
  Serial.println("\nInitializing");
  Serial.println(data);
  sscanf(data, "[%02d:%02d:%02d]%15s=%02d", &hour, &minute, &second, string, &number);
  Serial.println(hour);
  Serial.println(minute);
  Serial.println(second);
  Serial.println(string);
  Serial.println(number);
}

    
void loop() {}

Here is the result.

Initializing
[08:30:15]1.2.3.4=99
8
30
15
1.2.3.4=99
0

Arank:
Anyway, I added another variable to hold that value, but the last one, the "number" still don't work, do you know why?

Because "1.2.3.4" is a string less than 15 characters long?

Your sscanf parameter tells to get a string of 15 characters length ("%15s") behind the ']'.

jurs:
Because "1.2.3.4" is a string less than 15 characters long?

Your sscanf parameter tells to get a string of 15 characters length ("%15s") behind the ']'.

Ok, but the delimiter shouldn't be the '='?
Anyway, I tried to remove the 15, with "%s" and the result is exactly the same...

It will only work it fixed lengths? I tried with "%7s" and it works.

Arank:
It will only work it fixed lengths? I tried with "%7s" and it works.

sscanf() is not a tokenizer function.

As any character (except the null character) is valid for a string, %s will take the whole string if there is no length limit, including digits and equals sign. And if you want to use a length limit, the limit must be correct like "%15s" for a 15 character string or "%7s" for a seven character string.

If you want to tokenize your string while not knowing about string lengths, you'd better use strtok() for seperating the different parts of the string.

Arank:
Ok, but the delimiter shouldn't be the '='?
Anyway, I tried to remove the 15, with "%s" and the result is exactly the same...

It will only work it fixed lengths? I tried with "%7s" and it works.

You could try something like %15[^=] to read a string up to but not including the equal sign.

jurs:
sscanf() is not a tokenizer function.

As any character (except the null character) is valid for a string, %s will take the whole string if there is no length limit, including digits and equals sign. And if you want to use a length limit, the limit must be correct like "%15s" for a 15 character string or "%7s" for a seven character string.

If you want to tokenize your string while not knowing about string lengths, you'd better use strtok() for seperating the different parts of the string.

Hmm, Ok thanks jurs, I'm already using strtok(), I tought sscanf() should be easier.

christop:
You could try something like %15[^=] to read a string up to but not including the equal sign.

Thanks christop, your suggestion works like a charm!!

Delta_G:
There are very few things from regular C++ that got cut out of Arduino due to memory limitations. One of those things is variable length formatters. They just aren't supported.

Thanks for you answer Delta_G, but christop suggestion works.

Ok, that part is done.

But now I'm having trouble trying to do the same thing in another part of my sketch.

#include <SPI.h>
#include <Ethernet.h>

char *data = "<body>Current IP Address: 123.45.6.789</body>";
IPAddress IP;

void setup() {
  Serial.begin(115200);
  Serial.println("Initializing");
  Serial.println(data);
  sscanf(data, "Current IP Address: %d.%d.%d.%d</body>", &IP[0], &IP[1], &IP[2], &IP[3]);
  Serial.println(IP);
}

    
void loop() {}

The serial monitor:

Initializing
<body>Current IP Address: 123.45.6.789</body>
0.0.0.0

Any toughts of what I'm doing wrong?

is missing from your sscanf() string.

aarg:

is missing from your sscanf() string.

Oh damn, thanks aarg!