1

So, after some searching and googling, i can not figure out how to extract a value between two tokens in a char array. here is some of my code:

    char *data= (char *) malloc( 50);
    strcpy(data, "123 123 123 abcdef/456->ghijklm/789 123 123");

I need to extract "abcdef" as Str1 and "ghijkm" as Str2.

The first solution that everyone recommend is strtok as follow:

str1 = strtok(temp, "/");    // str1=abcdef

but how about the secound one? i mean str2, so.

Q1: How do i extract ghijkmn as str2?

Q2: Is there any other existing utility function I can leverage? or any other solution to deal with this kind of situation?

[Added:] What i need is all of strings separated by white spaces. all of "123"s are in desired format except that one is different. I need only two part of it as mentioned above.

7
  • 2
    You tagged this [C], but used the new keyword, which is C++ only. Commented Dec 21, 2016 at 15:35
  • 2
    What defines the start of "abcdef"? It is clearly not space, because space marks the beginning of string '"123"'. On what basis should we skip over "123", and only match "abcdef"? Commented Dec 21, 2016 at 15:37
  • 123 is a sample. The delimiter between those strings is white space. Commented Dec 21, 2016 at 15:39
  • 3
    If you want the first string delimited by whitespace, then it is "123". So (again), how are you saying the expected result is "abcdef"? Or maybe you want the first 3 strings skipped? Or maybe you want the first string that ends with a "/"? You have not been clear. Commented Dec 21, 2016 at 15:41
  • 1
    You should have more examples of that string to establish a pattern (one could be: some_junk 1st_text_that_we_care_about/some_numeric_junk->2nd_text_that_we_care_about/some_other_junk). Commented Dec 21, 2016 at 15:58

4 Answers 4

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

char *between(const char *str, char start, char end){
//return between start and end. However, start and end are not included.
    const char *s = NULL, *e;
    if(!str || !*str) return NULL;
    if((e = strchr(str+1, end)) == NULL)
        return NULL;//end character not found
    for(int i = e-str-1; i >= 0; --i){
        if(str[i] == start){
            s = str + i + 1;
            break;
        }
    }
    if(!s)
        return between(e, start, end);//start character not found
    int len = e - s;
    char *ret = malloc(len + 1);
    if(ret){
        memcpy(ret, s, len);
        ret[len] = 0;
    }
    return ret;
}

int main(void){
    const char *data = "123 123 123 abcdef/456->ghijklm/789 123 123";
    char *str1 = between(data, ' ', '/');

    if(str1){
        printf("str1: '%s'\n", str1);
        char *str2 = between(data, '>', '/');//use strstr+strlen+1 for after str1, or save search position
        if(str2)
            printf("str2: '%s'\n", str2);
        free(str1);free(str2);
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

"However A and B are not included", what are A and B? Not seen in your function.
@abelenky Thanks, I fixed that typo.
1

So, if you want all the strings and just some part of one of them, you can use the following piece of code if and only if the location of 'abcdef/456->ghijklm/789' in data array is fixed:

                //data ="123 123 123 123 123 123 123" abcdef/456->ghijklm/789 123");
                char temp[/*strlen(data)*/];
                char temp2[/*strlen(data)*/];
                char *splitPtr, *p, *abcdef, *ghijklm, _789;
                splitPtr = data;
                splitCounter = 0;
                for (char *p = strtok_r(data, " ", &splitPtr); p; p = strtok_r(NULL, " ", &splitPtr)) {
                    if (splitCounter == _the_location_of_special_text) {
                        strcpy(temp, p);                        
                        abcdef = strtok(temp, "/");
                        char *gt = strchr(p, '>')+1;
                        int index = (int)(gt - p);                        
                        strcpy(temp2, p+index);

                        ghijklm = strtok(temp2, "/");

                        _789 = strrchr( p, '/' )+1;
                    }
                    else {
                    //use the p as 123
                         }
                    splitCounter += 1;
                }
                printf ("Part 1: %s\n,Part 2: %s\n,Part 3: %s\n", abcdef, ghijklm , _789);

The output:

Part 1: abcdef

Part 2: ghijklm

Part 3: 789

Comments

1

IDEOne Code

#include <stdio.h>

int main(void)
{

    char text[]="123 123 123 abcdef/456->ghijklm/789 123 123";
    char* ptr = strtok(text, " ");
    char* slash;

    char* str1;
    char* str2;

    while(ptr)
    {
        if (slash = strstr(ptr, "/"))
        {
            *slash = '\0';
            str1 = ptr;
            ptr = ++slash;
            break;
        }
        ptr = strtok(NULL, " ");
    }

    str2 = strtok(ptr, ">");
    while(ptr)
    {
        if (slash = strstr(ptr, "/"))
        {
            *slash = '\0';
            str2 = ptr;
            break;
        }
        ptr = strtok(NULL, " ");
    }

    printf("Found a: %s; and b: %s\n", str1, str2);
    return 0;
}

Output

Found a: abcdef; and b: ghijklm

Comments

1

So from what I understand, you just want to extract the fully alphabetic strings from your char [] array. If this is the case, you can just parse the words using strtok, and test if the string has all alphabetic letters using isalpha from <ctype.h>.

Something like this could work:

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

int
main(int argc, char *argv[]) {
    char data[] = "123 123 123 abcdef/456->ghijklm/789 123 123";
    char *word;
    const char *delim = " /->";
    int i, validlet, strnum = 1;

    word = strtok(data, delim);
    while (word) {
        validlet = 0;
        for (i = 0; word[i]; i++) {
            if (!isalpha(word[i])) {
                break;
            }
            validlet++;
        }
        if (validlet == strlen(word)) {
            printf("Found str %d: %s\n",strnum, word);
            strnum++;
        }
        word = strtok(NULL, delim);
    }

    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.