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.

+3


source to share


2 answers


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 stored fscanf

.... C11 ยง7.21.6.2 12

An 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.

+1


source


Use %n

to get the length of the conversion and then check that the string does end with:



void checkString(const char *s)
{
  int i, j, n = 0;

  if (sscanf(s, "first%dsecond%dj%n", &i, &j, &n) == 2 && s[n] == '\0') 
  {
    printf("%s", s);
  }
}

      

+3


source







All Articles