How to compare strings containing numbers by letters in C
I need to compare strings comparing letters and numbers, letters and number occurrence in C.
For example, strings "first%dsecond%dj"
should be considered equal to any string, eg "first[number]second[number]j"
.
I tried to do it like this:
char *c_i
int i, j;
if (sscanf(c_i, "first%dsecond%dj", &i, &j) == 2 &&
c_i[strlen(in) - 2] == 'j') {
printf("%s", c_i);
}
but sscanf ignores everything after the last number, so lines like this "first%dsecond%dthird%dj"
also give true value and are printed.
Usually sscanf
only cares about the values โโof the letters before the last specifier, and I would like to find something that also takes into account the letters after, for example, say a comparator that checks whole strings and gets any number but a number.
Of course I can do this by creating my own scanner char*
, but I would like to avoid it if there is an easier way.
source to share
Change @unwind's good answer.
Use "%n"
to record the current scan position and "*"
to cancel the need to save to int
.
n
... The corresponding argument must be a pointer to a signed integer into which the number of characters read from the input stream so far by this function call must be storedfscanf
.... C11 ยง7.21.6.2 12An optional suppress assignment character
*
. ยง7.21.6.2 3
// return true on match
bool IE_compare(const char *c_i) {
int n = 0;
sscanf(c_i, "first%*dsecond%*dj%n", &n);
return n > 0 && c_i[n] == '\0';
}
Note. The format string can be encoded as separate read literals for alternate reads.
sscanf(c_i, "first" "%*d" "second" "%*d" "j" "%n", &n);
The above will match leading whitespace up to a number such as as "first +123second -456j"
it "%d"
allows. To avoid:
int n1, n2,
int n = 0;
sscanf(c_i, "first%n%*dsecond%n%*dj%n", &n1, &n2, &n);
return n > 0 && !isspace((unsigned char) c_i[n1]) &&
!isspace((unsigned char) c_i[n2]) && c_i[n] == '\0';
The above will match numbers with a leading type sign as "first+123second-456j"
it "%d"
allows. To avoid:
sscanf(c_i, "first%n%*dsecond%n%*dj%n", &n1, &n2, &n);
return n > 0 && isdigit((unsigned char) c_i[n1]) &&
isdigit((unsigned char) c_i[n2]) && c_i[n] == '\0';
// or
int n = 0;
sscanf(c_i, "first%*[0-9]second%*[0-9]j%n", &n);
return n > 0 && c_i[n] == '\0';
What remains somewhat unclear is if a number is required. "... and the appearance of a number" implies "yes". Should it "firstsecondj"
match? The above answers are not accepted.
source to share