我试图将一个字符串解析成更小的字符串,提取一些值,然后我想检查这些值中是否有任何一个是骗局...
这是我蹩脚的代码:)
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="INVITE sip:alice1@open-ims.test SIP/2.0\nCall-ID: mndfdnf8e4953t984egnue@open-ims.test To: <sip:alice2@open-ims.test>;<sip:alice@open-ims.test>;<sip:alice4@open-ims.test>;<sip:alice5@open-ims.test>;<sip:alice6@open-ims.test>;<sip:alice@open-ims.test>;<sip:alice8@open-ims.test>;<sip:alice9@open-ims.test>;<sip:alice10@open-ims.test>;<sip:alice11@open-ims.test>;<sip:alice12@open-ims.test>;";
char * tch;
char * saved;
char * array[50];
int count = 0;
tch = strtok (str,"<:;>");
while (tch != NULL)
{
int savenext = 0;
if (!strcmp(tch, "sip"))
{
savenext = 1;
}
printf ("%s\n",tch);
tch = strtok (NULL, "<:;>");
if (savenext == 1)
{
saved = tch;
}
if ( count == 0 ) {
array[count] = saved;
count ++;
}
if ( count > 0 ) {
int i = 0;
while (i < count ) {
if (array[count] == saved ) {
printf("FOUND!");
}
i++;}
}
}
}
我要做的是检查是否在字符串中两次找到相同的用户名,但我对指针缺乏经验阻止了我这样做。我不明白为什么这些值不会添加到数组中。
欢迎和感谢任何帮助
最佳答案
你已经完成了
if ( count == 0 ) {
array[count] = saved;
count ++;
}
也就是说你将saved
的地址存入array[count]
。在此操作中,没有字符串被复制。
然后你做:
if (array[count] == saved ) {
printf("FOUND!");
}
上面比较了存储在array[count]
中的值和存储在saved
中的地址。此操作不会比较存储在其中的字符串。
因此,如果 array[count]
中的地址 0x1234abcd
指向字符串“alice”并且 saved
指向字符串“alice”存储在另一个内存位置 0xdeadbeef
然后 array[count] == string
将与在这种情况下不同 0x1234abcd == 0xdeadbeef
正在完成.要比较这两个字符串,您需要执行 strcmp (array[count], saved) == 0
。
注意你有
while (i < count ) {
if (array[count] == saved ) {
printf("FOUND!");
}
i++;
}
在上面的代码中,您已经递增了i
,但访问array
的count
是一次静态的,并且不依赖于count
在 i
上。应该是array[i]
你已经完成了
if (count == 0)
{
array[count] = saved;
count ++
}
if (count > 0)
{
/* Here you try to search if the 'saved' is in the aray
but if it is not there you have NOT inserted it anywhere
into the array
*/
}
因为当 count > 0
时您没有输入 saved
指向的字符串,所以除了第一个之外的唯一字符串不会被存储在 array
中。因此,只要发现新字符串不在 if (count > 0)
block 中的字符串中,就应该将其保存到数组中。就像以下部分中描述的那样:
if (count > 0)
{
int i = 0;
while (i < count)
{
/* note use of strcmp */
if (strcmp (array[i], saved) == 0)
{
printf ("FOUND!"); /* if it was found break immediately */
break;
}
i++;
}
if (i == count) /* if there was no match then only i == count */
{ /* in other cases when dupes are there i<count as we used break */
array[count] = saved;
count++;
}
}
这是修改后的代码,它反射(reflect)了上述变化。
#include <stdio.h>
#include <string.h>
int main (void)
{
char str[] =
"INVITE sip:alice1@open-ims.test SIP/2.0\nCall-ID: mndfdnf8e4953t984egnue@open-ims.test To: <sip:alice2@open-ims.test>;<sip:alice@open-ims.test>;<sip:alice4@open-ims.test>;<sip:alice5@open-ims.test>;<sip:alice6@open-ims.test>;<sip:alice@open-ims.test>;<sip:alice8@open-ims.test>;<sip:alice9@open-ims.test>;<sip:alice10@open-ims.test>;<sip:alice11@open-ims.test>;<sip:alice12@open-ims.test>;";
char *tch;
char *saved;
char *array[50];
int count = 0, i;
tch = strtok (str, "<:;>");
while (tch != NULL)
{
int savenext = 0;
if (!strcmp (tch, "sip"))
{
savenext = 1;
}
// printf ("%s\n", tch);
tch = strtok (NULL, "<:;>");
if (savenext == 1)
{
saved = tch;
}
if (count == 0)
{
array[count] = saved;
count++;
}
else if ((count > 0) && (savenext == 1))
{
int i = 0;
while (i < count)
{
if (strcmp (array[i], saved) == 0)
{
printf ("FOUND!");
break;
}
i++;
}
if (i == count)
{
array[count] = saved;
count++;
}
}
}
for (i = 0; i < count; i++)
printf ("\n%s", array[i]);
}
编辑 1:
回复您的评论:
假设 strtok
匹配了 "sip",然后它使 saveptr = 1
读取下一个和 tch
中的标记,即用户名信息并在 saveptr
的帮助下将其保存到 array
中。在下一次迭代中,请注意 tch
指向存储在数组中的用户名信息。所以 strcmp
失败,因为它不是“sip”(包含用户名信息)。所以在这种情况下,saved
虽然没有被修改,但它仍然保留以前的值,它再次进入 if (count > 0)
block 。因此,一个用户信息在您的流程中被检查两次。你应该做的
if ((count > 0) && (savenext == 1))
{
/* Then insert */
}
上面的代码说的是,如果 saveptr ==
那么 saved
需要保存在 array
中,这就是为什么你接过旗帜 savenext
。
我也更新了代码。现在它正确地指出只有一个副本。
我会建议重新设计代码并使其更加简洁。可能您想详细了解一下这些指针,以使其变得更好。
关于C 在数组中添加和搜索已解析的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6255169/