C добавление и поиск проанализированных данных в массиве - PullRequest
0 голосов
/ 06 июня 2011

Я пытаюсь разобрать строку на меньшие, извлекая некоторые значения, а затем я хочу проверить, является ли какое-либо из этих значений дублирующим ...

Вот мой хромой код:)

#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 Ответ

3 голосов
/ 06 июня 2011

Вы сделали

if ( count == 0 ) {
array[count] = saved;  
count ++;  
}

Это означает, что вы сохраняете адрес saved в array[count].В этой операции не было скопировано ни одной строки.

Затем вы делаете:

if (array[count] == saved ) {
  printf("FOUND!");
}

Приведенное выше сравнение сравнивает значение, сохраненное в array[count], с адресом, сохраненным в saved.Эта операция не сравнивает строки, хранящиеся в них.

Так что, если адрес 0x1234abcd в array[count] указывает на строку «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, который является статическим для одного прохода и не зависит от 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).Как описано в следующем сегменте:

  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.

Я тоже обновил код.Теперь он правильно говорит, что есть только один дубликат.

Я бы порекомендовал изменить код и сделать его немного более чистым.Возможно, вы хотели бы еще раз взглянуть на указатели в деталях, чтобы сделать его лучше.

...