diff --git a/README.md b/README.md
index 6e71095..17e2ffd 100644
--- a/README.md
+++ b/README.md
@@ -201,12 +201,16 @@ Creates an owning object for the specified range of bytes. The range should be s
Creates an owning object from the given C string. The string should be safe to pass to
`free(3)` function. Destination is assigned using `str_assign` semantics.
-#### sorting
+#### sorting and searching
`void str_sort(const str_cmp_func cmp, str* const array, const size_t count)`
Sorts the given array of `str` objects. A number of typically used sorting functions is
provided (see `str.h` file).
+`const str* str_search(const str key, const str* const array, const size_t count)`
+Binary search for the given key. The input array must be sorted using `str_order_asc`.
+Returns a pointer to the string matching the key, or NULL.
+
#### Memory allocation
By default the library uses `malloc(3)` for memory allocations, and calls `abort(3)`
if the allocation fails. This behaviour can be changed by hash-defining `STR_EXT_ALLOC`
diff --git a/str.c b/str.c
index 3d33520..7904eb8 100644
--- a/str.c
+++ b/str.c
@@ -326,4 +326,16 @@ void str_sort(const str_cmp_func cmp, str* const array, const size_t count)
{
if(array && cmp && count > 1)
qsort(array, count, sizeof(array[0]), cmp);
+}
+
+// searching
+const str* str_search(const str key, const str* const array, const size_t count)
+{
+ if(!array || count == 0)
+ return NULL;
+
+ if(count == 1)
+ return str_eq(key, array[0]) ? array : NULL;
+
+ return bsearch(&key, array, count, sizeof(str), str_order_asc);
}
\ No newline at end of file
diff --git a/str.h b/str.h
index a57f856..bbff328 100644
--- a/str.h
+++ b/str.h
@@ -179,6 +179,9 @@ int str_order_desc_ci(const void* const s1, const void* const s2);
// sort array of strings
void str_sort(const str_cmp_func cmp, str* const array, const size_t count);
+// searching
+const str* str_search(const str key, const str* const array, const size_t count);
+
#ifdef __cplusplus
}
#endif
diff --git a/str_test.c b/str_test.c
index 777275c..31371ac 100644
--- a/str_test.c
+++ b/str_test.c
@@ -305,6 +305,21 @@ void test_sort_ci(void)
assert(str_eq_ci(src[3], str_lit("aaa")));
}
+static
+void test_search(void)
+{
+ str src[] = { str_lit("z"), str_lit("zzz"), str_lit("aaa"), str_lit("bbb") };
+ const size_t count = sizeof(src)/sizeof(src[0]);
+
+ str_sort(str_order_asc, src, count);
+
+ assert(str_search(src[0], src, count) == &src[0]);
+ assert(str_search(src[1], src, count) == &src[1]);
+ assert(str_search(src[2], src, count) == &src[2]);
+ assert(str_search(src[3], src, count) == &src[3]);
+ assert(str_search(str_lit("xxx"), src, count) == NULL);
+}
+
int main(void)
{
// tests
@@ -322,6 +337,7 @@ int main(void)
test_composition();
test_sort();
test_sort_ci();
+ test_search();
return puts("OK.") < 0;
}