我有一个格式为Contact:
的字符串<abcde@123.343:5060;gr=xyz123>;+g134,<more_text>
我需要在开场<
和结束>
之间提取内容
可能有<
和>
的多个实例,但我必须从参数gr=
所在的对中获取内容(仅出现一次)。
为了解决这个问题,我所做的是:
ptr = strstr(str,"gr=");
if(ptr)
{
temp1= ptr;
while(*temp1 && *temp1!='<')
{
temp1--;
}
strncpy(newstring,temp1,ptr-temp1); //will copy upto start of gr
temp2 = strstr(ptr,">")
if(temp2)
strncat(newstring,ptr,temp2-ptr); // copy remaining string till it finds closing '>'
}
它工作正常,但我想知道是否有任何方法可以避免while循环并向后退?
答案 0 :(得分:2)
您可以搜索第一次出现'&lt;'和'&gt;'看看'gr ='是否落在他们之间。
lt = strchr(ptr,'<');
gt = strchr(ptr,'>');
gr = strstr(ptr,"gr=");
if ( gr > lt && gr < gt) {
strncat(newstring,lt,gt-lt);
}
答案 1 :(得分:1)
您可以使用strcspn获取下一个标记的偏移量。您的代码没有循环来查找下一个实例,但是这段代码确实如此。我假设你的循环在那之外,也许你需要适应一点。
size_t offset = 0, length;
offset = strcspn(str, "<");
while (str[offset] != '\0')
{
++offset;
length = strcspn(str + offset, ">");
ptr = strstr(str + offset, "gr=");
if (ptr != NULL && ptr - str < offset + length)
{
strncpy(newstring, ptr + offset, length);
/* do what you need with newstring here */
}
offset = strcspn(str + offset + length + 1, "<");
}
答案 2 :(得分:1)
您可以通过解析字符串一次而不是更多来完成此操作(与此处的其他答案不同)。如果子字符串没有重复的字符,下面的代码可以处理您提供的任何子字符串。
我们的想法是在任何<
和>
之间复制任何内容;当复制查找子字符串时,如果找不到,则继续,直到找到它为止。
char *str = "<abcde@123.343:5060;gr=xyz123>;+g134,<more_text>";
char result[MAX_LENGTH];
size_t i = 0, j = 0;
char copying = 0, found = 0;
const char *subs = "gr=";
const int subs_len = 3;
while ((char ch = *str))
{
if (ch == '<')
copying = 1;
else if (ch == '>')
{
if (found)
break;
else
{
copying = 0;
i = j = 0;
}
}
else if (copying)
{
result[i++] = ch;
if (!found)
{
if (ch == subs[j])
{
++j;
if (j == subs_len)
found = 1;
}
else
{
j = (ch == subs[0]) ? 1 : 0;
}
}
}
++str;
}
result[i] = '\0';