あなたはやった
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」を指してarray[count] == string
いる場合、この場合と同じではありません0x1234abcd == 0xdeadbeef
。2つの文字列を比較するには、実行する必要がありますstrcmp (array[count], saved) == 0
。
あなたがすることに注意してください
while (i < count ) {
if (array[count] == saved ) {
printf("FOUND!");
}
i++;
}
上記のコードでは、インクリメントしましたが、1回のパスで静的であり、に依存しないwithに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
whenが指す文字列を入力しないため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]);
}
編集1:
コメントへの回答:strtok
「sip」が一致したとするsaveptr = 1
と、次の読み取りとトークンの入力、つまりユーザー名情報を作成し、の助けを借りてtch
保存します。次の反復では、配列に格納されたユーザー名情報を指していることに注意してください。したがって、「sip」(ユーザー名情報が含まれている)ではないため、失敗します。したがって、この場合、は変更されていませんが、以前の値を保持し、ブロックに再び入ります。したがって、1つのユーザー情報がプロセスで2回チェックされます。やったほうがいいarray
saveptr
tch
strcmp
saved
if (count > 0)
if ((count > 0) && (savenext == 1))
{
/* Then insert */
}
上記のコードが言っていることは、もしsaveptr ==
それsaved
がに保存される必要があるならarray
、それがあなたが旗を取った理由ですsavenext
。
私もコードを更新しました。これで、重複が1つしかないことが正しく通知されます。
コードを再設計して、もう少しクリーンにすることをお勧めします。おそらく、ポインタをより良くするために、ポインタについてもう一度詳しく調べたいと思うでしょう。