I have dynamic string like: "/users/5/10/fnvfnvdjvndfvjvdklchsh"
and also dynamic format like "/users/%u/%d/%s"
, how to check these strings matches?
As string i mean char[255]
or char* str = malloc(x)
.
I tried use sscanf
but i dont know number of arguments and types, if i do:
int res = sscanf(input, format);
I have stack overflow, or can i allocate stack to prevent this? Example like this:
void* buffer = malloc(1024);
int res = sscanf(input, format, buffer);
I would like have function like this:
bool stringMatches(const char* format, const char* input);
stringMatches("/users/%u/%d/%s", "/users/5/10/fnvfnvdjvndfvjvdklchsh"); //true
stringMatches("/users/%u/%d/%s", "/users/5/10"); //false
stringMatches("/users/%u/%d/%s", "/users/-10/10/aaa"); //false %u is unsigned
Do you see any solution?
Thanks in advance.
I don't think that there is a scanf
-like matching function in the standard lib, so you will have to write your own. Replicating all details of the scanf
behaviour is difficult, but it's probably not necessary.
If you allow only %
and a limited selection of single format identifiers without size, width and precision information, the code isn't terribly complex:
bool stringMatches(const char *format, const char *input)
{
while (*format) {
if (*format == '%') {
format++;
switch(*format++) {
case '%': {
if (*input++ != '%') return false;
}
break;
case 'u':
if (*input == '-') return false;
// continue with 'd' case
case 'd': {
char *end;
strtol(input, &end, 0);
if (end == input) return false;
input = end;
}
break;
case 's': {
if (isspace((uint8_t) *input)) return false;
while (*input && !isspace((uint8_t) *input)) input++;
}
break;
default:
return false;
}
} else {
if (*format++ != *input++) return false;
}
}
return (*input == '\0');
}
Some notes:
strtol
. If you want to include floating-point number formats, you could use strtod
for that, if your embedded system provides it. (You could also parse stretches of isdigit()
chars as valid numbers.)'u'
case falls through to the 'd'
case here. The function strtoul
parses an unsigned long, but it allows a minus sign, so that case is caught explicitly. (But the way it is caught, it won't allow leading white space.)