在 C 中的同一个字符串上多次应用 strstr()
Applying strstr() multiple times on same string in C
我正在尝试编写一段代码,使用 strstr 提取 和 标签之间的所有 words/strings。但它似乎只是卡在提取的第一个字符串上,即 "quick"。如何让代码在提取第一个字符串后继续运行?
#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] != '[=10=]')
{
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] = '[=10=]';
printf("%s",res);
n++;
}
return 0;
}
这一行:
ret = strstr(feed, needle)+6;
您总是从 feed
字符串的开头开始搜索。您需要将不同的起点传递给 strstr
,您在 ter
中已有该起点。所以你应该能够做这样的事情:
ter = feed;
while (ter != NULL)
{
ret = strstr(ter, needle) + 6;
...
有了这个,您的搜索开始将继续向下移动 feed
字符串。
您的代码中还有一些其他问题:
strstr()
如果找不到匹配项,可以 return NULL - 你需要检查它,否则你的程序会崩溃。
- 你需要
free()
你malloc()
的记忆
- 正如@iharob 指出的那样“Do not cast
malloc()
”
你需要让 ret
指针指向字符串中的当前位置,并在每次迭代时增加它的长度,并将 ret
传递给第一个 strstr()
而不是 feed
,请查看此实现
#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] != '[=10=]')
{
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] = '[=10=]';
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;
}
我正在尝试编写一段代码,使用 strstr 提取 和 标签之间的所有 words/strings。但它似乎只是卡在提取的第一个字符串上,即 "quick"。如何让代码在提取第一个字符串后继续运行?
#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] != '[=10=]')
{
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] = '[=10=]';
printf("%s",res);
n++;
}
return 0;
}
这一行:
ret = strstr(feed, needle)+6;
您总是从 feed
字符串的开头开始搜索。您需要将不同的起点传递给 strstr
,您在 ter
中已有该起点。所以你应该能够做这样的事情:
ter = feed;
while (ter != NULL)
{
ret = strstr(ter, needle) + 6;
...
有了这个,您的搜索开始将继续向下移动 feed
字符串。
您的代码中还有一些其他问题:
strstr()
如果找不到匹配项,可以 return NULL - 你需要检查它,否则你的程序会崩溃。- 你需要
free()
你malloc()
的记忆
- 正如@iharob 指出的那样“Do not cast
malloc()
”
你需要让 ret
指针指向字符串中的当前位置,并在每次迭代时增加它的长度,并将 ret
传递给第一个 strstr()
而不是 feed
,请查看此实现
#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] != '[=10=]')
{
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] = '[=10=]';
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;
}