在C中对同一个字符串应用strstr()多次

时间:2021-10-13 22:56:21

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?

我正在编写一个代码,使用strstr提取和标记之间的所有单词/字符串。但它似乎只是被卡在了第一个被提取的字符串,即“快”。提取第一个字符串后,如何让代码继续运行?

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

2 个解决方案

#1


2  

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

您需要使ret指针指向字符串中的当前位置,并在每次迭代中按长度递增,并将ret传递给第一个strstr()而不是提要,请查看此实现

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

#2


1  

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:

您总是从提要字符串的开头开始搜索。您需要将一个不同的起点传递给strstr,这是您在ter中已经拥有的。所以你应该可以这样做:

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. 如果没有找到匹配项,strstr()可以返回NULL——您需要检查它,否则程序会崩溃。
  3. You need to free() the memory you malloc()
  4. 您需要释放您malloc()的内存
  5. As @iharob points out "Do not cast malloc()"
  6. 正如@iharob指出的“不要使用malloc()”

#1


2  

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

您需要使ret指针指向字符串中的当前位置,并在每次迭代中按长度递增,并将ret传递给第一个strstr()而不是提要,请查看此实现

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

#2


1  

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:

您总是从提要字符串的开头开始搜索。您需要将一个不同的起点传递给strstr,这是您在ter中已经拥有的。所以你应该可以这样做:

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. 如果没有找到匹配项,strstr()可以返回NULL——您需要检查它,否则程序会崩溃。
  3. You need to free() the memory you malloc()
  4. 您需要释放您malloc()的内存
  5. As @iharob points out "Do not cast malloc()"
  6. 正如@iharob指出的“不要使用malloc()”