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; } 
4

2 Answers

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; } 
4

On this line:

ret = strstr(feed, needle)+6; 

You are always starting your search from the beginning of the feed string. You need to pass a different starting point to strstr, which you already have in ter. So you should be able to do something like this:

ter = feed; while (ter != NULL) { ret = strstr(ter, needle) + 6; ... 

With this the start of your search will keep moving farther down the feed string.

There are some other issues in your code:

  1. strstr() can return NULL if it doesn't find a match - you need to check for that or you program will crash.
  2. You need to free() the memory you malloc()
  3. As @iharob points out "Do not cast malloc()"
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like