- ベストアンサー
データの比較の仕方について
--宣言-- typedef struct { int len;/* ptrの長さ */ unsigned char *ptr; } aaa; char abc[128]; --宣言end---- HIKAKU(aaa *d1,char *d2) { d1,d2にはそれぞれデータが入力されてくる。 d2はabcのポインタ。 } d1,d2の実体を比較し一致するか否か判定したいのですが、 何分初心者なもので・・・ アドバイス頂けないでしょうか? 宜しくお願い致します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>できればstr系ではなく、mem系を使用する >ようにと言われているのですが・・・。 ずいぶんと、イジワルなことを言われちゃいましたね。 では、がんばってみましょう。 { char *ptr1, *ptr2; int maxleng; maxleng = (d1->len - strlen(d2) < 0)?strlen(d2):d1->len ; ptr1 = malloc((size_t)maxleng+1); ptr2 = malloc((size_t)maxleng+1); memset(ptr1, 0x00, maxleng+1); memset(ptr2, 0x00, maxleng+1); memcpy(ptr1, d1->ptr, d1->len); memcpy(ptr2, d2, strlen(d2)); if( memcmp( ptr1, ptr2, maxleng ) == 0 ) { // 一致した場合の処理 } else { // 一致しなかった場合の処理 } free(ptr1);free(ptr2); } ----------------------------------------------- どうでしょう?判りにくくなったでしょ?(笑) memcmpで比較する2つの領域のサイズが、memcmpの第3パラメータ で指定する数値よりも小さいと、落っこちる可能性が あるんで、maxlengを求めるようにしました。 私なら、間違い無くstrcmp()を使います。楽だし。見やすいし。 それか、whileしながら1文字ずつ比較する内部関数を作ります。 >比較対照がunsigned char と charのためキャストしなけ >ればコンパイルエラーとかなりませんか? エラーにはなりませんが、気になるなら、 strcmp((char *)ptr, d2) または、 memcmp((void *)ptr1, (void *)ptr2, (size_t)maxlen) にしてみましょう。でも、ここまでするのはヤリスギな気がします。 何にキャストするのが正解かは、string.hとかmemory.hの中を 見たり、HELP(とかman)を見れば判ります。
その他の回答 (4)
- toysmith
- ベストアンサー率37% (570/1525)
strlen(d2)とd1->lenが違えば(=長さが違えば)既に一致しないわけですから比較する必要はありません。 よって、比較はmemcmp(d2, d1->ptr, d1->len)でオッケーです。 if (strlen(d2) == d1->len) { if (!memcmp(d2, d1->ptr, d1->len)) { /* 一致 */ return ; } } /* 不一致 */ キャストについては C:viod*は全てのポインタを受け入れるので必要なし C++:void*とunsigned char *,char *の変換についてワーニングがでるので(void*)へのキャストをしてもよい。 標準C/C++の時ですのでコンパイルオプションによってはCでもワーニングになったりエラーになったりします。
- lan-c
- ベストアンサー率80% (4/5)
先ほどの私の回答にバグがありました。ごめんなさい。 たとえば、 d1->ptr が "abc" で、 d2が "abcd"の場合、 d1->lenは、d1->ptrの長さなので、 3 になりますよね。 そうすると、 strncmp( "abc", "abcd", 3 ) になります。 これでは、先頭の3文字しか比較していないため、「一致している」 となってしまいます。(gccで確認しました) やっぱり、d1->ptrをヌルターミネートしている別変数にいれた方が よさそうですね。(頭悪くてごめんなさい) ---------------------------------------- { char *ptr; ptr = malloc((size_t)d1->len + 1); memset(ptr, 0x00, d1->len+1); memcpy(ptr, d1->ptr, d1->len); if( strcmp( ptr, d2 ) == 0 ) { // 一致した場合の処理 } else { // 一致しなかった場合の処理 } free(ptr); } ------------------------------------------ きっと、もっとスマートなやり方あるんでしょうね。 でも、比較自体はカンペキになったでしょ?
- lan-c
- ベストアンサー率80% (4/5)
わざわざ、d1->lenで、長さをもっているんで d1->ptrはヌルターミネートしていない可能性 がありますね。 ---------------------------------------------- if( strncmp( d1->ptr, d2, d1->len ) == 0 ) { // 一致した場合の処理 } else { // 一致しなかった場合の処理 } ---------------------------------------------- こっちの方が安全かも知れません。 ただし、strncmp()はクセがある関数なので、 HELPなどを良くみてください。 もし、d1->ptrがヌルターミネートされているのなら、 cockyさんの方法の方が安全確実で、お勧めです。
- cocky
- ベストアンサー率57% (232/402)
単純に if( strcmp( d1->ptr, d2 ) == 0 ) { // 一致した場合の処理 } else { // 一致しなかった場合の処理 } でいいんじゃないですか?
補足
ありがとうございます。 ただちょっと補足なのですが、 できればstr系ではなく、mem系を使用する ようにと言われているのですが・・・。 また、比較対照がunsigned char と char のためキャストしなければコンパイルエラー とかなりませんか?