C在数组中添加和搜索已解析的数据

时间:2011-06-06 16:34:24

标签: c arrays parsing pointers segment

我正在尝试将字符串解析为较小的字符串,提取一些值,然后我想检查这些值中的任何一个是否是一个欺骗...

这是我的蹩脚代码:)

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


            }
 }

我要做的是检查字符串中是否找到两次相同的用户名,但是我缺乏指针经验会阻止我这样做。我无法弄清楚为什么这些值不会被添加到数组中。

欢迎任何帮助和赞赏

1 个答案:

答案 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 arraycount一次传递是静态的,并且不依赖于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中的下一个和令牌,即用户名信息并将其保存到arraysaveptr的帮助。在下一次迭代中,注意tch指向存储在数组中的用户名信息。所以strcmp失败,因为它不是“sip”(包含用户名信息)。因此,在这种情况下,saved虽然未被修改但仍保留先前的值,该值再次进入if (count > 0)块。因此,在您的流程中,两次检查一个用户信息。你应该做

if ((count > 0) && (savenext == 1))
{
     /* Then insert */
}

上述代码表示,如果saveptr ==saved需要array保存savenext,那么您就可以使用{{1}}标志。

我也更新了代码。现在它正确地说明只有一个副本。

我建议重新设计代码并使其更干净。您可能希望再次详细了解指针,以使其更好。