bsearch() - Finding a string in an array of structs

bsearch, c, string, struct

Solution

You should implement your own comparator function and pass it in. The most important (non-trivial) thing to keep in mind here is that according to the standard,

The implementation shall ensure that the first argument is always a pointer to the key.

This means that you can write a comparator that compares a string such as `target` and a `dictionary_t` object. Here is a simple function that compares your stucts to a string:

int compare_string_to_dict(const void *s, const void *d) {
    return strncmp(s, ((const dictionary_t *)d)->word, sizeof(((dictionary_t *)0)->word));
}

You would then pass it by name as a normal function pointer to `bsearch`:

result = bsearch(target, dictionary, dict_length, sizeof(dictionary_t), compare_string_to_dict);

Note that `target` does not need to have its address passed in since it is no longer mocking a struct.

In case you are wondering, `sizeof(((dictionary_t *)0)->word)` is an idiomatic way of getting the size of `word` in `dictionary_t`. You could also do `sizeof(dictionary[0].word)` or define a constant equal to 30. It comes from here.

Problem

I have a struct that looks like this: ``` typedef struct dictionary_t{ char word[30]; int foo; int bar; } dictionary_t; ``` Which forms an ordered array: ``` dictionary_t dictionary[100]; ``` I would like to search this array for a string using bsearch() and get a pointer to the struct. So far this has worked: ``` dictionary_t* result; char target[30] = "target"; result = bsearch(&target, dictionary, dict_length, sizeof(dictionary_t), (int(*)(const void*,const void*)) strcmp); ``` However this is a bit of a hack and only works because the string happens to be the first member of the struct. What would be a better way to find a string within an array of structs and return a pointer to the struct?

Original source

Related problems