Reputation: 1281
I am doing a code practice using C language.
As below codes,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _CRT_SECURE_NO_WARNINGS
int ACDSort(const void *p1, const void *p2);
int Compare(const void *pKey, const void *pValue);
int main(void)
{
char * strAry[4] = {"Hardware","Cookie","Boy","Power"};
char * destStr = "Cookie";
//qsort((void*)strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), ACDSort);
char **ptrAdr = (char**)bsearch((void*)destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);
printf("%s\n", *ptrAdr);
}
int Compare(const void *pKey, const void *pValue) {
char *key = ((char*)pKey);
char *value = *((char**)pValue);
return strcmp(key, value);
}
int ACDSort(const void *p1, const void *p2) {
char * n1 = *((char**)p1);
char * n2 = *((char**)p2);
int ret;
if (strlen(n1) > strlen(n2))
ret = 1;
else if (strlen(n1) < strlen(n2))
ret = -1;
else
ret = 0;
return ret;
}
I called bsearch
to find the string of cookie
.
The problem is that the error occurred when I erased the //
in order to sort the array based on the string length.
I don't know why the error was executed because I think that qsort
couldn't be able to significant affect to my codes.
Could you tell me the reason why the error occurred returning null pointer when erasing the //
?
Ps. I used qsort
and bsearch
to get familiar with pointer variables.
Upvotes: 0
Views: 125
Reputation: 6407
Type of destStr
can be changed to be the same as type of strAry
, e.g.:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int Compare(const void *pKey, const void *pValue)
{
char *key = *((char**)pKey);
char *value = *((char**)pValue);
return strcmp(key, value);
}
int main(void)
{
char * strAry[4] = { "Hardware", "Cookie", "Boy", "Power" };
char * destStr[1] = { "Cookie" }; // Type changing
qsort(strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);
char **ptrAdr = (char**)bsearch((void*)destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);
printf("%s\n", *ptrAdr);
}
Also, if you use C language (and compiler) consider using strcmp
directly as callback function that compares two elements.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*int Compare(const void *pKey, const void *pValue)
{
char *key = *((char**)pKey);
char *value = *((char**)pValue);
return strcmp(key, value);
}*/
int main(void)
{
char * strAry[4] = { "Hardware", "Cookie", "Boy", "Power" };
char * destStr[1] = { "Cookie" }; // Type changing
//qsort(strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);
qsort(strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), strcmp);
//char **ptrAdr = (char**)bsearch((void*)destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);
char **ptrAdr = (char**)bsearch(destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), strcmp);
printf("%s\n", *ptrAdr);
}
Note:
This solution has one disadvantage that appears as ...
warning: passing argument 5 of ‘bsearch’ from incompatible pointer type [enabled by default]
But it works (I have tried with GCC version 4.8.2 and MS Visual studio 12.0)
Upvotes: -1
Reputation: 213950
bsearch
uses binary search, that's why. Binary search requires the data to be sorted. Sort the string array in alphabetic order and it will work.
As a side note, you need to get rid of all those superfluous casts, all they do is to hide potential bugs.
Working program after fixes and clean-up:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare (const void* p1, const void* p2);
int main (void)
{
const char* strAry[4] = {"Boy", "Cookie", "Hardware", "Power"};
const char* key = "Cookie";
char** ptrAdr = bsearch(key,
strAry,
sizeof(strAry)/sizeof(*strAry),
sizeof(*strAry),
compare);
printf("%s\n", *ptrAdr);
}
int compare (const void* p1, const void* p2)
{
const char* s1 = p1;
const char* s2 = *(const char* const*)p2;
return strcmp(s1, s2);
}
p2 will end up a const
void pointer to a const char*
, which is why we get that weird-looking cast when striving for const-correctness.
Upvotes: 5