Anis_Stack
Anis_Stack

Reputation: 3452

using sscanf to check string format

I want to compare my string to a giving format.

the format that I want to use in the check is :

"xxx://xxx:xxx@xxxxxx" // all the xxx are with variable length

so I used the sscanf() as follow :

if (sscanf(stin,"%*[^:]://%*[^:]:%*[^@]@") == 0) { ... }

is it correct to compare the return of scanf to 0 in this case?

Upvotes: 3

Views: 2180

Answers (2)

chux
chux

Reputation: 153478

OP's suggestion is close.

@Jonathan Leffler is correct in that comparing the result of a specifier-less sscanf() against 0 does not distinguish between a match and no-match.

To test against "xxx://xxx:xxx@xxxxxx", (and assuming any part with "x" needs at least 1 matching), use

int n = 0;
sscanf(stin, "%*[^:]://%*[^:]:%*[^@]@%*c%n", &n);
if (n > 0) {
  match();
}

There is a obscure hole using this method with fscanf(). A stream of data with a \0 is a problem.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753735

You will only get zero back if all the fields match; but that won't tell you diddly-squat in practice. It might have failed with a colon in the first character and it would still return 0.

You need at least one conversion in there that is counted (%n is not counted), and that occurs at the end so you know that what went before also matched. You can never tell if trailing context (data after the last conversion specification) matched, and sscanf() won't backup if it has converted data, even if backing up would allow the trailing context to match.

For your scenario, that might be:

char c;
int  n;

if (sscanf(stin, "%*[^:]://%*[^:]:%*[^@]@%n%c", &n, &c) == 1)

This requires at least one character after the @. It also tells you how many characters there were up to and including the @.

Upvotes: 1

Related Questions