bsearch () ne trouve pas mon article

Quelqu’un pourrait-il me dire pourquoi bsearch () dans le code suivant ne trouve pas l’élément “getwidth” dans la liste? J’ai essayé plusieurs compilateurs et cela ne fonctionne avec aucun d’eux, donc ça doit être un bogue dans mon code. Cependant, je ne vois vraiment pas ce qui ne va pas là-bas. Le rappel passé à bsearch () renvoie toujours quelque chose qui est! = 0 mais quand même, il n’est appelé que 5 fois, puis NULL est renvoyé par bsearch () bien qu’il n’ait pas parcouru tous les éléments. Pourquoi donc?

Voici le code:

#include  #include  #include  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; } 

Et voici le résultat que ce programme génère:

 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 

Je ne vois vraiment pas pourquoi ça ne marche pas bien que ce ne soit vraiment que quelques lignes. Est-ce que quelqu’un peut éclairer ce comportement étrange? Merci!

Parce que wxSize_methods n’est pas sortingé par ordre alphabétique insensible à la casse. Vous devez sortinger wxSize_methods par strcasecmp avant la recherche binary.

Vous comparez les noms de méthode en utilisant strcasecmp() mais selon que votre liste n’est pas correctement sortingée (par exemple “delete” <"GetWidth"). Utilisez strcmp() place ou sortingez votre liste.