2017-01-21 2 views
0

Я пытаюсь использовать bsearch, но результат поиска продолжает оставаться NULL. Мой массив имен сортируется по алфавиту. Я новичок в C и вам нужна ваша помощь, чтобы понять, где я ошибаюсь.Проблема функции Bsearch в C

Вот массив

// arrays of children's names 
char *chBamba[] = { "Bambale1", "Bamb2", "Bamb3", "Bambook4", "Bambookle5" }; 
char *chBisli[] = { "Bislile1", "Bischick2", "Bislile3", "Bis4" }; 
int nBamba = sizeof(chBamba)/sizeof(*chBamba); 
int nBisli = sizeof(chBisli)/sizeof(*chBisli); 
// array of workers 
Worker a[] = { { "Printf", 10, NULL, 0 } ,{ "Bisli", 20, chBisli, nBisli }, 
{ "TapooChips", 3, chBamba, nBamba },{ "Bamba", 19, chBamba, nBamba } }; 

Это структура

typedef struct{ 
char name[LEN]; // worker's name 
int salary; // worker's salary 
char **childArr; // array of children names 
int numChildren; // number of children}Worker; 

функция сравнения

int compareNames(const void* child1, const void* child2){ 
    char* ch1 = (char*)child1; 
    char* ch2 = (char*)child2; 
    return strcmp(ch1, ch2); 
} 

И bsearch

char childName[10]; 
    char* nameFound; 
    printf("Please enter a child name to search for :"); 
    scanf("%s",childName); 

    for (i = 0; i < 4; i++) 
    { 
    nameFound =(char*) bsearch(childName,a[i].childArr, a[i].numChildren, sizeof(a[i].childArr)/ sizeof(a[i].childArr[0]), compareNames); 
    } 

Это C не C++. То, что я изучаю прямо сейчас. Я использую VS 2015, и он работает как для C, так и для C++. Я редактирую некоторые изменения, чтобы заставить его работать правильно и компилировать. Так сравнить это

int compareNames(const void * s1, const void * s2){ 
const char *key = (char*)s1; 
const char * const *arg = (char**)s2; 
return strcmp(key, *arg); 

}

и bsearch является

nameFound = (char*)bsearch(childName,a[i].childArr, a[i].numChildren, sizeof(char*), compareNames); 
+0

Нет необходимости вводить тип 'bsearch'. Он возвращает 'void *'. – RoadRunner

+0

@RoadRunner: Правильно. Тем не менее OP, скорее всего, использует либо компилятор C++, либо MS-VS. – alk

+0

Да я использую VS2015 и там он просит отливки –

ответ

1

Сравнения функция передается указатели к элементам массива.

От man bsearch:

The compar routine is expected to have two arguments which point to the key object and to an array member ....

элементы массива имеют тип char *, поэтому функция сравнения должна выглядеть следующим образом:

int compareNames(const void * pvchild1, const void * pvchild2) 
{ 
    const char ** ppc1 = (const char **) pvchild1; // casting necessary with C++ 
    const char ** ppc2 = (const char **) pvchild2; // casting necessary with C++ 

    return strcmp(*ppc1, *ppc2); 
} 

Чтобы дополнительно покрыть случай, когда массив содержал нуль-указатель Вы можете сделать:

... 

    return strcmp(ppc1 ?*ppc1 :"", ppc2 ?*ppc2 :""); 
} 

вызовов bsearch() как это:

char * p = childName; 
    nameFound =(char*) bsearch(// casting necessary with C++ 
    &p, 
    a[i].childArr, 
    a[i].numChildren, 
    sizeof *(a[i].childArr), 
    compareNames 
); 

Также в качестве примечания: Код, который вы показать defintily не C, но C++, так как это

Worker a[] = { 
{ "Printf", 10, NULL, 0 } ,{ "Bisli", 20, chBisli, nBisli }, 
{ "TapooChips", 3, chBamba, nBamba },{ "Bamba", 19, chBamba, nBamba } 
}; 

не компилировать C, но сообщите об ошибке:

error: initializer element is not constant 
+0

Если я перехожу к тому, что вы набрали, я получаю en error «Исключение брошено на 0x0F581340 (ucrtbased.dll) в HW3_GordonIgor.exe: 0xC0000005: Место для обнаружения нарушения доступа 0x34736942. Если есть обработчик для этого исключения, программа может быть благополучно продолжил ». –

+0

@GordonIgor: вы не хотите передавать 'NULL' в' bsearch() '(как адрес 1 элемента массива, который нужно искать), как вы бы сделали для 1-го элемента' {"Printf", 10, NULL, 0} '. – alk

+0

@GordonIgor: Чтобы отладить это, вы можете захотеть скомпилировать с помощью символов, запустите код внутри отладчика, чтобы трассировать программы (программы) по очереди, проверяя значения соответствующих переменных, чтобы узнать, что действительно происходит. Если тогда возникает * конкретный * вопрос, не стесняйтесь возвращаться сюда. – alk