C adding and searching parsed data in array
I'm trying to parse a string into smaller ones, extracting some values and then I want to check if any of these values is a dupe...
Here's my lame code :)
#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 = 开发者_StackOverflow社区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++;}
}
}
}
What I have to do is check if the same username is found twice in the string, but my lack of experience with pointers prevents me from this. I can't figure out why the values won't be added to the array.
Any help is welcome and appreciated
You have done
if ( count == 0 ) {
array[count] = saved;
count ++;
}
Which means that you save the address of the saved
into array[count]
. In this operation no strings were copied.
Then you do:
if (array[count] == saved ) {
printf("FOUND!");
}
The above compares the value stored in array[count]
with the address stored in saved
. This operation does not compare the strings stored in them.
So if an address 0x1234abcd
in array[count]
points to a string "alice" and saved
points to the string "alice" stored in another memory location 0xdeadbeef
then array[count] == string
would not be same as in this case 0x1234abcd == 0xdeadbeef
is being done. To compare the two strings you need to do strcmp (array[count], saved) == 0
.
Note that you do
while (i < count ) {
if (array[count] == saved ) {
printf("FOUND!");
}
i++;
}
In the above code, you have incremented i
but accessed the array
with count
which is static for one pass, and does not depend on i
. It should be array[i]
You have done
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
*/
}
Because you do not enter the string pointed by saved
when count > 0
so the unique strings except the first one does not gets stored in the array
. So you should save the new sting into the array whenever you find that it is not in the sting in the if (count > 0)
block. Like as described in the following segment:
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++;
}
}
Here is the modified code, which reflect the above changes.
#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:
Answer to your comment:
Say the strtok
has matched "sip" , then it makes saveptr = 1
reads in the next and token in tch
, ie, the username info and saves it into array
with the help of saveptr
. In the next iteration note that tch
points to the username info that was stored in the array. So the strcmp
fails as it is not "sip" (contains the user name info). So in this case the saved
is although not modified it still holds the previous value, which enters the if (count > 0)
block again. So one user information is checked twice in your process. You should do
if ((count > 0) && (savenext == 1))
{
/* Then insert */
}
What the above code says that, if saveptr ==
then the saved
needs to be saved in the array
, that is why you took the flag savenext
.
I have updated the code too. Now it correctly tells that there is only one duplicate.
I would recommend to redesign the code and make it a bit more clean. Probably you would like to have another look about the pointers in details to make it better.
精彩评论