Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matching trailing text in sscanf?

Tags:

c

scanf

This is related to sscanf usage - how to verify a completed scan vs an aborted scan but it's an edge case not covered by that question.

char entry[] = "V2X_3_accepted";
int d1,d2,ret1,ret2;
ret1 = sscanf(entry,"V2X_%d_expected",&d1);
ret2 = sscanf(entry,"V2X_%d_received",&d2);

Expected result: ret1==0; ret2==0; d1, d2 undefined.

Actual result: ret1==1; ret2==1; d1=d2=3.

Using %n at the end won't help, as the match strings are equal length. Is there some neat trick to match the trailing text without performing a consecutive strncmp or similar?

like image 914
SF. Avatar asked Dec 19 '16 11:12

SF.


1 Answers

Using "%n" works fine. @user3121023

Recommend using " %n" to allow optional trailing white-space like a '\n' to pass "V2X_3_expected\n" and to check the %n result to fail "V2X_3_expected 123".

char entry[] = "V2X_3_accepted";

int d1,d2;
int n1 = 0;
int n2 = 0;

sscanf(entry,"V2X_%d_expected %n",&d1, &n1);
sscanf(entry,"V2X_%d_received %n",&d2, &n2);
if (n1 > 0 && entry[n1] == '\0') Success_expected(d1);
else if (n2 > 0 && entry[n2] == '\0') Success_received(d2);
else Fail(entry);

Initialize n1 to a value that would never be set is scanning reached the "%n" specifier. n1 = 0; works well in most cases like with OP's format "V2X_%d_ ...".

n1 = -1; /* and (n1 >= 0 */ also works with short formats like " %n".

like image 169
chux - Reinstate Monica Avatar answered Nov 19 '22 07:11

chux - Reinstate Monica