I'm trying to compare an input of characters with a string that can be of the format "!x" where x is any integer.
What's the easiest way to do this? I tried
int result = strcmp(input,"!%d");
which did not work.
I'm trying to compare an input of characters with a string that can be of the format "!x" where x is any integer.
What's the easiest way to do this? I tried
int result = strcmp(input,"!%d");
which did not work.
Here's one way to do it:
int is_bang_num(const char *s) {
if (*s != '!') {
return 0;
}
size_t n = strspn(s + 1, "0123456789");
return n > 0 && s[1 + n] == '\0';
}
This verifies that the first character is !
, that it is followed by more characters, and that all of those following characters are digits.
You see, scanf()
family of functions return a value indicating how many parameters where converted.
Even books usually ignore this value and it leads programmers to ignore that it does return a value. One of the consequences of this is Undefined Behavior when the scanf()
function failed and the value was not initialized, not before calling scanf()
and since it has failed not by scanf()
either.
You can use this value returned by sscanf()
to check for success, like this
#include <stdio.h>
int
main(void)
{
const char *string;
int value;
int result;
string = "!12345";
result = sscanf(string, "!%d", &value);
if (result == 1)
fprintf(stderr, "the value was: %d\n", value);
else
fprintf(stderr, "the string did not match the pattern\n");
return 0;
}
As you can see, if one parameter was successfuly scanned it means that the string matched pattern, otherwise it didn't.
With this approach you also extract the integral value, but you should be careful because scanf()
's are not meant for regular expressions, this would work in very simple situations.
Since the stirng must begin with a ! and follow with an integer, use a qualified strtol()
which allows a leading sign character. As OP did not specify the range of the integer, let us allow any range.
int is_sc_num(const char *str) {
if (*str != '!') return 0;
str++;
// Insure no spaces- something strtol() allows.
if (isspace((unsigned char) *str) return 0;
char *endptr;
// errno = 0;
// By using base 0, input like "0xABC" allowed
strtol(str, &endptr, 0);
// no check for errno as code allows any range
// if (errno == ERANGE) return 0
if (str == endptr) return 0; // no digits
if (*endptr) return 0; // Extra character at the end
return 1;
}
If you want to test that a string matches a format of an exclamation point and then some series of numbers, this regex: "!\d+" will match that. That won't catch if the first number is a zero, which is invalid. This will: "![1,2,3,4,5,6,7,8,9]\d*".