sscanf help, please :)

well then, I'm implementing a serial interface with my arduino and I'm having some trouble parsing a string.

the string is:

char * temp = "t[2342]";

I wanted to parse it with sscanf, is there a way to parse it and verify format at the same time?

for example: sscanf(temp, "t[%ud]", tempLong);
this way I would know it sarts with a 't' then a '[' followed by a long and ended with ']'

I know, this format is not right xD.. I just wanted you to get the point :)

Thank you very much!!
You can try using the return value, which is the number of successfully parsed fields. A field (aka "input item") is read successfully if at least one character passed its criteria and was read for it. Another interesting feature is "%*", which suppresses writing the field in an argument. And also "%n" which writes in the argument the current position in the parsed string.

Now, I am not saying that the result is elegant, but technically, you can create quite complex criteria using those specifications. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
  const char* temp = "t[0123]";
  int ret;
  int n, i, j, k;
  char c;

  //The following scan restricts the integer in 4 characters (inc. leading 0s)
  ret = sscanf(temp, "t[%n %n%4d%c%n", &i, &j, &n, &c, &k);

  cout << "sscanf returns: " << ret << endl;
  cout << "i: " << i << endl;
  cout << "j: " << j << endl;
  cout << "n: " << n << endl;
  cout << "c: '" << c << '\'' << endl;
  cout << "k: " << k << endl;

  cout << (((ret == 2) &&  // 1 for %d + 1 for %c; %n don't count
            (i == j) &&    // no leading space before the integer
            (n >= 0) &&    // its non-negative; you can use %u instead
            (c == ']') &&  // the closing bracket follows the integer
            (temp[k] == 0) // the closing bracket is the last character
            ) ? "ok" : "nok")
       << endl;
}

Regards
I found it out:
1
2
3

sscanf(Interface.getBuffer(),"t%*[[]%lu%[]]", &tempLong[0]) == 2


this way the function checks for the 't' them checks and ignores the '[' then reads the number as a unsigned long and finally checks and reads the ']'.. but as I only give it one variable it only stores the unsigned long! :D

Thanks anyway ;)
You can not give it just one variable. You need to give it two variables, or it will overwrite some arbitrary content in memory. You may not see it, and it may not crash, but it is happening. Also, the %*[[] reads arbitrary number of consecutive left square brackets without storing them. To read a single left square bracket use just [.
Thank you simeonz!! I think I understood it ;)
Now I wanted to ask something:

of the string is: "[sometexthere]"

how can I parse it so that '[' stays in one variable '"sometexthere" stays in another and for last ']' stays in another

 
sscanf("p[234,43.887]","p[%i,%[0123456789.-]s%c",&tempInt, &tempBuff, &tempChar)


I can get the tempInt = 234;
the tempBuff = 43.887;
but tempChar = <00> //something is wrong here :(


thank you again!


You don't need to additionally specify 's' suffix when already using the bracket notation. That should be the problem.
sscanf("p[234,43.887]","p[%i,%[0123456789.-]s%c",&tempInt, &tempBuff, &tempChar)

P.S. The second specification will parse 43.887, but will also parse 1.2.3.4, and --.--.-- The built-in %u, %d, %f are preferable to custom sets. At least, that's what I would use.
Last edited on
Topic archived. No new replies allowed.