bsearch() не находит мой предмет

Может кто-нибудь сказать мне, почему bsearch() в следующем коде не находит пункт "getwidth" в списке? Я пробовал несколько компиляторов, и они не работают ни с одним из них, поэтому это должно быть ошибкой в ​​моем коде. Тем не менее, я действительно не вижу, что там не так. Обратный вызов, переданный bsearch(), всегда возвращает что-то!= 0, но, тем не менее, он вызывается только 5 раз, а затем bsearch() возвращает NULL, хотя он итерировал не по всем элементам. Это почему?

Вот код:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

typedef struct wxLuaBindMethod
{
    const char *name;
    int method_type;
    void *wxluacfuncs;
    int wxluacfuncs_n;
    void *basemethod;
} wxLuaBindMethod;

#define WXLUAMETHOD_CONSTRUCTOR 0x0001
#define WXLUAMETHOD_METHOD 0x0002
#define WXLUAMETHOD_DELETE 0x2000

wxLuaBindMethod wxSize_methods[] = {
    { "DecBy", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "DecTo", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "GetHeight", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "GetWidth", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "IncBy", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "IncTo", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "IsFullySpecified", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "Scale", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "Set", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "SetDefaults", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "SetHeight", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "SetWidth", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "delete", WXLUAMETHOD_METHOD|WXLUAMETHOD_DELETE, NULL, 1, NULL},
    { "op_add", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_div", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_eq", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_iadd", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_idiv", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_imul", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_isub", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_mul", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_ne", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_set", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "op_sub", WXLUAMETHOD_METHOD, NULL, 1, NULL},
    { "wxSize", WXLUAMETHOD_CONSTRUCTOR, NULL, 1, NULL},
    { 0, 0, 0, 0 },
}; 

int wxLuaBindMethod_CompareByNameFnGet(const void *p1, const void *p2)
{
    int v = strcasecmp(((const wxLuaBindMethod*)p1)->name, ((const wxLuaBindMethod*)p2)->name);

    printf("CMP: %s = %s? --> %d\n", ((const wxLuaBindMethod*)p1)->name, ((const wxLuaBindMethod*)p2)->name, v);

    return v;
}

int main(int argc, char *argv[])
{
    wxLuaBindMethod methodItem = { "getwidth", 10, 0, 0, 0 };
    wxLuaBindMethod *wxlMethod;

    wxlMethod = (wxLuaBindMethod *)bsearch(&methodItem, wxSize_methods, 25, sizeof(wxLuaBindMethod), wxLuaBindMethod_CompareByNameFnGet);

    printf("RESULT: %p\n", wxlMethod);

    return 0;                                                       
} 

И вот результат, который генерирует эта программа:

CMP: getwidth = delete? --> 3
CMP: getwidth = op_isub? --> -8
CMP: getwidth = op_iadd? --> -8
CMP: getwidth = op_div? --> -8
CMP: getwidth = op_add? --> -8
RESULT: 0x0

Я действительно не понимаю, почему это не работает, хотя на самом деле это всего лишь несколько строк. Может кто-нибудь пролить свет на это странное поведение? Спасибо!

2 ответа

Решение

Так как wxSize_methods не сортируется по регистронезависимому алфавитному порядку. Вы должны отсортировать wxSize_methods от strcasecmp перед бинарным поиском.

Вы сравниваете имена методов, используя strcasecmp() но в соответствии с этим ваш список не отсортирован должным образом (например, "удалить" <"GetWidth"). использование strcmp() вместо этого или сортируйте свой список.

Другие вопросы по тегам