C言語関係掲示板

過去ログ

No.1023 構造体配列に対するbsearch

[戻る] [ホームページ]
No.13034

構造体配列に対するbsearch
投稿者---shuji(2004/03/03 23:28:54)


構造体配列でメンバごとにbsearchで検索できるようにしたいのですが、
何故か構造体の先頭のメンバしか検索できません。

例えば・・・
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{
    char a[3];
    char b[3];
    int c;
} REC;
int compar(const REC *x,const REC *y)
{
    return (strcmp(x->a,y->a));
}
void main(void)
{
    REC x[]={
        {"10","20",5},
        {"30","25",15},
        {"33","30",30},
        {"48","42",35},
        {"50","45",59},
        {"92","65",77}
    };

    REC *p,temp;

    printf("key入力==> ");
    scanf("%s",temp.a);

    p=bsearch(temp.a,x,6,sizeof(REC),(int (*)(const void *, const void *))compar);

    if(p==NULL)
        printf("該当なし\n");
    else
        printf("%s  %s  %d\n",p->a,p->b,p->c);

    return;
}


↑のように構造体の先頭のメンバに対してはbsearchで検索できました。


でも今度は2番目のメンバをbsearchで検索しようとすると
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{
    char a[3];
    char b[3];
    int c;
} REC;
int compar(const REC *x,const REC *y)
{
    return (strcmp(x->b,y->b));
}
void main(void)
{
    REC x[]={
        {"10","20",5},
        {"30","25",15},
        {"33","30",30},
        {"48","42",35},
        {"50","45",59},
        {"92","65",77}
    };

    REC *p,temp;

    printf("key入力==> ");
    scanf("%s",temp.b);

    p=bsearch(temp.b,x,6,sizeof(REC),(int (*)(const void *, const void *))compar);

    if(p==NULL)
        printf("該当なし\n");
    else
        printf("%s  %s  %d\n",p->a,p->b,p->c);

    return;
}


実際にkeyと該当する値があってもbsearchからはNULLが返ってきてるようで…


過去ログ等調べてみましたがそれらしきものはありませんでした。
どうすれば良いかご指摘お願いします。

No.13035

Re:構造体配列に対するbsearch
投稿者---YuO(2004/03/04 01:36:33)


>構造体配列でメンバごとにbsearchで検索できるようにしたいのですが、
>何故か構造体の先頭のメンバしか検索できません。

bsearchの使い方が間違っているからです。


動く,というのを正しいものに簡単に書き換えると,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char a[3];
    char b[3];
    int c;
} REC;

int compar (const void * key, const void * element)
{
    const REC * p = element;
    return strcmp(key, p->a);
}

int main (void)
{
    REC x[] = {
        { "10", "20", 5},
        { "30", "25", 15},
        { "33", "30", 30},
        { "48", "42", 35},
        { "50", "45", 59},
        { "92", "65", 77},
    }, * p;
    char buf[3];

    printf("key入力==> ");
    scanf("%s", buf);

    p = bsearch(buf, x, sizeof(x) / sizeof(x[0]), sizeof(x[0]), compar);

    if (p == NULL)
        printf("該当なし\n");
    else
        printf("%s  %s  %d\n", p->a, p->b, p->c);

    return 0;
}

となります。

bsearchの比較関数に渡される第一引数はbsearchの第一引数であって,
検索する配列要素ではないことに注意して下さい。


それから,
int (*)(const REC *, const REC *);

int (*)(const void *, const void *);
にキャストしたところで,正しく呼べることは保証されていません。
変換やキャストは比較関数の中で行う必要があります。

理由の無いキャストは避けるのが鉄則です。
#コンパイラの警告やエラーをもみ消す結果になるから。


No.13041

Re:構造体配列に対するbsearch
投稿者---shuji(2004/03/04 22:52:28)


ご指導ありがとうございます。


>bsearchの使い方が間違っているからです。

>bsearchの比較関数に渡される第一引数はbsearchの第一引数であって,
>検索する配列要素ではないことに注意して下さい。

今回初めてbsearchを使ったのでよく理解していませんでした^^;
キャストや変換についてもまだ理解が足りてないようなので
これからも頑張りたいと思います。
ありがとうございました。