Search code examples
c++cstringstrtokstrtol

Complex algorithm to extract numbers/number range from a string


I am working on a algorithm where I am trying the following output:

Given values/Inputs:

char *Var = "1-5,10,12,15-16,25-35,67,69,99-105"; int size = 29;

Here "1-5" depicts a range value, i.e. it will be understood as "1,2,3,4,5" while the values with just "," are individual values.

I was writing an algorithm where end output should be such that it will give complete range of output as:

int list[]=1,2,3,4,5,10,12,15,16,25,26,27,28,29,30,31,32,33,34,35,67,69,99,100,101,102,103,104,105;

If anyone is familiar with this issue then the help would be really appreciated. Thanks in advance!

My initial code approach was as:

if(NULL != strchr((char *)grp_range, '-'))
{
    int_u8 delims[] = "-";
    result = (int_u8 *)strtok((char *)grp_range, (char *)delims);

    if(NULL != result)
    {
        start_index = strtol((char*)result, (char **)&end_ptr, 10);
        result = (int_u8 *)strtok(NULL, (char *)delims);
    }

    while(NULL != result)
    {
        end_index = strtol((char*)result, (char**)&end_ptr, 10);
        result = (int_u8 *)strtok(NULL, (char *)delims);
    }

    while(start_index <= end_index)
    {
        grp_list[i++] = start_index;
        start_index++;
    }
}

else if(NULL != strchr((char *)grp_range, ','))
{
    int_u8 delims[] = ",";
    result = (unison_u8 *)strtok((char *)grp_range, (char *)delims);

    while(result != NULL)
    {
        grp_list[i++] = strtol((char*)result, (char**)&end_ptr, 10);
        result = (int_u8 *)strtok(NULL, (char *)delims);
    }
}

But it only works if I have either "0-5" or "0,10,15". I am looking forward to make it more versatile.


Solution

  • You're issue seems to be misunderstanding how strtok works. Have a look at this.

    #include <string.h>
    #include <stdio.h>
    
    int main()
    {
            int i, j;
            char delims[] = " ,";
            char str[] = "1-5,6,7";
            char *tok;
            char tmp[256];
            int rstart, rend;
    
            tok = strtok(str, delims);
    
            while(tok != NULL) {
                    for(i = 0; i < strlen(tok); ++i) {
                            //// range
                            if(i != 0 && tok[i] == '-') {
                                    strncpy(tmp, tok, i); 
                                    rstart = atoi(tmp);
                                    strcpy(tmp, tok + i + 1); 
                                    rend = atoi(tmp);
                                    for(j = rstart; j <= rend; ++j)
                                            printf("%d\n", j); 
                                    i = strlen(tok) + 1;
                            }   
                            else if(strchr(tok, '-') == NULL)
                                    printf("%s\n", tok);
                    }   
    
                    tok = strtok(NULL, delims);
            }   
    
            return 0;
    }