2013-08-08 9 views
0

누구든지 다음 코드에서 bsearch()가 항목에서 "getwidth"항목을 찾지 못하는 이유를 말해 줄 수 있습니까? 몇 가지 컴파일러를 시도하고 아무도 함께 작동하지 그래서 내 코드 버그가 있어야합니다. 그러나, 나는 거기에서 무엇이 잘못되었는지 정말로 알지 못한다. bsearch()에 전달 된 콜백은 항상! = 0을 반환하지만 여전히 모든 항목에 대해 반복하지는 않았지만 bsearch()에 의해 5 번만 호출되고 NULL이 반환됩니다. 왜 그런가요? 여기 bsearch()가 내 항목을 찾지 못했습니다.

코드입니다 :

#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 

정말 정말 몇 비록 그것이 작동하지 않는 이유를 볼 수 없습니다 윤곽. 누군가가이 이상한 행동에 대해 밝힐 수 있습니까? 감사!

답변

3

wxSize_methods은 대소 문자를 구분하지 않는 알파벳순으로 정렬되지 않으므로 이진 검색을 수행하기 전에 wxSize_methodsstrcasecmp으로 정렬해야합니다.

+0

감사합니다. bsarch()가 문제를 해결하기 전에 strcasecmp() 비교와 함께 qsort()를 사용하십시오! – Andreas

0

strcasecmp()을 사용하여 메소드 이름을 비교하지만 목록이 올바르게 정렬되지 않았다고 (예 : "삭제"< "GetWidth"). 대신 strcmp()을 사용하거나 목록을 정렬하십시오.

+0

고마워요, 그건 속임수입니다. – Andreas