Question

Got an issue with working with a string in C. I have a string like this :

".>0and.<300"

Or

".>0 and .<280"

Or

".&gt;=0 and .&lt;=280"

The dot is representing the value x. I need to create a simpler string looking like:

"minimum:maximum"

eg 0:300. I tried to start looking for < and and to take the value in.

char *open = strrchr(string, '<');
char *end = strrchr(string, 'and');

Thks for any help !

Was it helpful?

Solution

  1. Replace all non-digit characters with ' '.
  2. Trim spaces at the start.
  3. Trim spaces between numbers, leave only one.
  4. Put '\0' after last digit.
  5. Replace the one space with ':'.

If the numbers may be inversed in order, you may use this (code this time, as you wish):

#include <string.h>
#include <stdio.h>

#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

int main()
{
  char src[] = ".>1220and.<300";
  char dstBuf[64]="ERROR";
  char* num1 = NULL;
  char* num2 = NULL;
  char* ptr = src;
  int indigit = 0;

  for (;*ptr; ptr++) {
    if (isdigit(*ptr)) {
      if (indigit == 0) {
        if (num1 == NULL) num1 = ptr;
        else              num2 = ptr;
        indigit = 1;
      }
    } else {
      indigit = 0;
    }
  }
  if (num1 != NULL && num2 != NULL) {
    int n1 = strtoll(num1, NULL, 10);
    int n2 = strtoll(num2, NULL, 10);
    sprintf(dstBuf, "%d:%d", MIN(n1,n2), MAX(n1,n2));
  } else if (num1 != NULL) {
    sprintf(dstBuf, "%s", num1);
  }

  printf("%s\n", dstBuf);

}

OTHER TIPS

How about finding the two numbers and ordering them with min and max ?

#include <stdio.h>
#include <ctype.h>

#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

int main(){
    char s[] = ".>=0 and .<=280";
    char *ptr = s;
    int a, b;

    while( ! isdigit(*ptr)) ptr++;
    a = atoi(ptr);
    while(isdigit(*ptr)) ptr++;
    while( ! isdigit(*ptr)) ptr++;
    b = atoi(ptr);

    printf("%d:%d\n", MIN(a, b), MAX(a, b));

    return 0;
} 

Notice that my code assumes that the string is well formed, you should add safety checks for the real thing.

EDIT

Here is a very basic parser that handles all cases and that does some safety checks.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main(){
    char s[] = ".>=0 and .<=280";
    char *ptr = s;
    int num;
    unsigned char equals, gt, lt;

    while(*ptr){
        /* consume the stuff before the digit */
        equals = gt = lt = 0;
        while(*ptr && ! isdigit(*ptr)){
            switch(*ptr){
                case '=':
                    equals = 1; break;
                case '<':
                    lt = 1; break;
                case '>':
                    gt = 1; break;
            }
            ptr++;
        }
        /* consume the digit */
        num = atoi(ptr);
        while(*ptr && isdigit(*ptr)) ptr++;

        /* do your stuff according to (gt, lt, equals, num) */
        printf("found comparison: gt=%d lt=%d equals=%d num=%d\n", gt, lt, equals, num);
    }

    return 0;
}

Here is how it works:

$ ./test 
found comparison: gt=1 lt=0 equals=1 num=0
found comparison: gt=0 lt=1 equals=1 num=280

If your need becomes any more complex than this, you should really look at proper parsing and lexing tools.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top