我正在尝试将字符串解析为较小的字符串,提取一些值,然后我想检查这些值中的任何一个是否是一个欺骗...
这是我的蹩脚代码:)
#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++;}
}
}
}
我要做的是检查字符串中是否找到两次相同的用户名,但是我缺乏指针经验会阻止我这样做。我无法弄清楚为什么这些值不会被添加到数组中。
欢迎任何帮助和赞赏
答案 0 :(得分:3)
你已经完成了
if ( count == 0 ) {
array[count] = saved;
count ++;
}
这意味着您将saved
的地址保存到array[count]
。在此操作中,没有复制任何字符串。
然后你做:
if (array[count] == saved ) {
printf("FOUND!");
}
以上将array[count]
中存储的值与saved
中存储的地址进行比较。此操作不会比较存储在其中的字符串。
因此,如果0x1234abcd
中的地址array[count]
指向字符串“alice”,saved
指向存储在另一个内存位置0xdeadbeef
中的字符串“alice”,则{ {1}}与此情况不同array[count] == string
正在进行中。要比较两个字符串,您需要执行0x1234abcd == 0xdeadbeef
。
请注意,你
strcmp (array[count], saved) == 0
在上面的代码中,您增加了 while (i < count ) {
if (array[count] == saved ) {
printf("FOUND!");
}
i++;
}
,但访问了i
array
,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
*/
}
因为saved
时没有输入count > 0
指向的字符串,所以除了第一个之外的唯一字符串不会存储在array
中。因此,只要您发现它不在if (count > 0)
块中的刺痛中,就应该将新的sting保存到数组中。如以下部分所述:
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++;
}
}
以下是修改后的代码,它反映了上述变化。
#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]);
}
<强> EDIT1:强>
回答你的意见:
假设strtok
与“sip”匹配,然后它会使saveptr = 1
读入tch
中的下一个和令牌,即用户名信息并将其保存到array
中saveptr
的帮助。在下一次迭代中,注意tch
指向存储在数组中的用户名信息。所以strcmp
失败,因为它不是“sip”(包含用户名信息)。因此,在这种情况下,saved
虽然未被修改但仍保留先前的值,该值再次进入if (count > 0)
块。因此,在您的流程中,两次检查一个用户信息。你应该做
if ((count > 0) && (savenext == 1))
{
/* Then insert */
}
上述代码表示,如果saveptr ==
,saved
需要array
保存savenext
,那么您就可以使用{{1}}标志。
我也更新了代码。现在它正确地说明只有一个副本。
我建议重新设计代码并使其更干净。您可能希望再次详细了解指针,以使其更好。