Search code examples
carraysstringstrstrstrstream

Applying strstr() multiple times on same string in C


I'm trying to write a code that extracts all words/strings between the and tags using strstr. But it seems that it just gets stuck to the first string extracted, which is "quick". How can I get the code to keep going after extracting the first string?

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

int main()
{

    char feed[] = "The <item> quick </item> brown <item> fox </item> jumps <item> over </item> the <item> lazy dog </item>";


    const char needle[] = "<item>";
    const char popo[] = "</item>";
    char *ret;
    char *ter;
    int n;
    n = 0;

    while (feed[n] != '\0')
    {
        ret = strstr(feed, needle)+6;
        ter = strstr(ret, popo);
        size_t len = ter - ret;
        char *res = (char*)malloc(sizeof(char)*(len+1));
        strncpy(res, ret, len);
        res[len] = '\0';

        printf("%s",res);
        n++;
    }
    return 0;
}

Solution

  • You need to make the ret pointer to point to the current position in the string, and increment it by length on each iteration, and pass ret to the first strstr() instead of feed, check out this implementation

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
    
        char       feed[]   = "The <item> quick </item> brown <item> fox </item> "
                              "jumps <item> over </item> the <item> lazy dog </item>";
        const char needle[] = "<item>";
        const char popo[]   = "</item>";
        char      *head;
        int n;
        n = 0;
    
        head = feed;
        while (feed[n] != '\0')
        {
            char  *tail;
            char  *copy;
            size_t length;
    
            head = strstr(head, needle);
            /*            ^ always start at the current position. */
            if (head == NULL)
             {
                fprintf(stderr, "Invalid input...???\n");
                return -1;
             }
            tail   = strstr(head, popo);
            length = tail - head - 6;
            head  += 6;
            if (length < 0)
             {
                fprintf(stderr, "Invalid input...???\n");
                return -1;
             }
            copy = malloc(length + 1);
            if (copy != NULL)
             {
                memcpy(copy, head, length);
                copy[length] = '\0';
    
                printf("*%s*\n", copy);
                /* If you are not going to keep it, free it */
                free(copy);
             }
            head += length; /* <-- this is the imprtant thing */
            n++;
        }
        return 0;
    }