Substrings in the middle of a String in C

GustRenan picture GustRenan · Apr 21, 2015 · Viewed 7.1k times · Source

I need to extract substrings that are between Strings I know.

I have something like char string = "abcdefg"; I know what I need is between "c" and "f", then my return should be "de".

I know the strncpy() function but do not know how to apply it in the middle of a string.

Thank you.

Answer

rubikonx9 picture rubikonx9 · Apr 21, 2015

Here's a full, working example:

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

int main(void) {
    char string[] = "abcdefg";

    char from[] = "c";
    char to[]   = "f";

    char *first = strstr(string, from);

    if (first == NULL) {
        first = &string[0];
    } else {
        first += strlen(from);
    }

    char *last = strstr(first, to);

    if (last == NULL) {
        last = &string[strlen(string)];
    }

    char *sub = calloc(strlen(string) + 1, sizeof(char));

    strncpy(sub, first, last - first);

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

    free(sub);

    return 0;
}

You can check it at this ideone.

Now, the explanation:

1.

    char string[] = "abcdefg";

    char from[] = "c";
    char to[]   = "f";

Declarations of strings: main string to be checked, beginning delimiter, ending delimiter. Note these are arrays as well, so from and to could be, for example, cd and fg, respectively.

2.

    char *first = strstr(string, from);

Find occurence of the beginning delimiter in the main string. Note that it finds the first occurence - if you need to find the last one (for example, if you had the string abcabc, and you wanted a substring from the second a), it might need to be different.

3.

    if (first == NULL) {
        first = &string[0];
    } else {
        first += strlen(from);
    }

Handle situation, in which the first delimiter doesn't appear in the string. In such a case, we will make a substring from the beginning of the entire string. If it does appear, however, we move the pointer by length of from string, as we need to extract the substring beginning after the first delimiter (correction thanks to @dau_sama). Depending on your specifications, this may or may not be needed, or another result might be expected.

4.

    char *last = strstr(first, to);

Find occurence of the ending delimiter in the main string. Note that it finds the first occurence.

As noted by @dau_sama, it's better to search for ending delimiter from the first, not from beginning of the entire string. This prevents situations, in which to would appear earlier than from.

5.

    if (last == NULL) {
        last = &string[strlen(string)];
    }

Handle situation, in which the second delimiter doesn't appear in the string. In such a case, we will make a substring until end of the string, so we get a pointer to the last character. Again, depending on your specifications, this may or may not be needed, or another result might be expected.

6.

    char *sub = calloc(last - first + 1, sizeof(char));

    strncpy(sub, first, last - first);

Allocate sufficient memory and extract substring based on pointers found earlier. We copy last - first (length of the substring) characters beginning from first character.

7.

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

Here's the result.

I hope it does present the problem with enough details. Depending on your exact specifications, you may need to alter this somehow. For example, if you needed to find all substrings, and not just the first one, you may want to make a loop for finding first and last.