{"id":6779,"date":"2025-01-25T00:01:14","date_gmt":"2025-01-25T08:01:14","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6779"},"modified":"2025-02-01T12:10:27","modified_gmt":"2025-02-01T20:10:27","slug":"using-the-bsearch-function-to-find-strings","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6779","title":{"rendered":"Using the <em>bsearch()<\/em> Function to Find Strings"},"content":{"rendered":"<p>When learning the <em>bsearch()<\/em> function, it helps to start with integers, as demonstrated in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6767\">last week&#8217;s Lesson<\/a>. When the data is more complex, however, additional programming kung-fu is required to sort and search. The first hill to climb in this adventure is to hunt down a string.<br \/>\n<!--more--><br \/>\nBefore setting out, remember that to find one string inside another you use <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=889\">the <em>strstr()<\/em> function<\/a>. For finding a single string in an array of strings, the <em>bsearch()<\/em> function works well.<\/p>\n<p>The issue with an array of strings is that it&#8217;s a cleverly disguised array of pointers: <\/p>\n<p><code>char *fruit[] = {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;\"cantalope\", \"grapefruit\", \"fig\", \"melon\",<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;\"banana\", \"apple\", \"kiwi\", \"lemon\"<br \/>\n};<\/code><\/p>\n<p>The <code>fruit[]<\/code> array holds the addresses of the strings it references. These addresses are character pointers. This data type is what&#8217;s referenced in the <em>qsort()<\/em> function, which sorts the array, as well as the <em>bsearch()<\/em> function, which searches for a matching string in the array.<\/p>\n<p>Here&#8217;s the <em>qsort()<\/em> function&#8217;s format:<\/p>\n<p><code>qsort( fruit, size, sizeof(char *), compare);<\/code><\/p>\n<p>The array and its size value come first (<code>size<\/code> is the number of elements). The next argument is the size of each element, which is not a string length. No, it&#8217;s the size of a character pointer, <code>char *<\/code>. Finally comes the <em>compare()<\/em> function&#8217;s name.<\/p>\n<p>Here are the arguments for the <em>bsearch()<\/em> function:<\/p>\n<p><code>bsearch( &key, fruit, size, sizeof(char *), compare );<\/code><\/p>\n<p>The address of string <code>key<\/code> is what the <em>bsearch()<\/em> function searches for. The rest of the arguments are the same as for the <em>qsort()<\/em> function.<\/p>\n<p>Both functions can share the same <em>compare()<\/em> function. For this operation the <em>strcmp()<\/em> function compares strings. But remember that the <em>compare()<\/em> function is sent two <em>void<\/em> pointers. These must be typecast to strings and properly addressed as pointer-pointers for the comparison to work:<\/p>\n<p><code>int compare(const void *a, const void *b)<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;return( strcmp(*(const char **)a,*(const char **)b) );<br \/>\n}<\/code><\/p>\n<p>The <code>(const char **)<\/code> typecast identifies each variable as a pointer-pointer, or the address of a string. (I find &#8220;address of a string&#8221; to be a better way to describe the pointer-pointer thing.) This value is an address, which is why the cast is prefixed with the <code>*<\/code> to dereference the address and represent the string itself. These two values are compared in the <em>strcmp()<\/em> function, with the result returned. This operation applies to both the <em>qsort()<\/em> and <em>bsearch()<\/em> functions to sort and search the array of strings.<\/p>\n<p>Here is sample code:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2025_01_25-Lesson.c\" rel=\"noopener\" target=\"_blank\">2025_01_25-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\nint compare(const void *a, const void *b)\r\n{\r\n    return( strcmp(*(const char **)a,*(const char **)b) );\r\n}\r\n\r\nint main()\r\n{\r\n    char *fruit[] = {\r\n        \"cantalope\", \"grapefruit\", \"fig\", \"melon\",\r\n        \"banana\", \"apple\", \"kiwi\", \"lemon\"\r\n    };\r\n    char *key;    <span class=\"comments\">\/* input buffer must be allocated *\/<\/span>\r\n    char **r;\r\n    int size;\r\n\r\n    <span class=\"comments\">\/* obtain array size *\/<\/span>\r\n    size = sizeof(fruit)\/sizeof(char *);\r\n\r\n    <span class=\"comments\">\/* locate a value *\/<\/span>\r\n    key = malloc(32);\r\n    if (key==NULL) exit(1);\r\n    printf(\"Fruit: \");\r\n    scanf(\"%s\",key);\r\n\r\n    <span class=\"comments\">\/* sort the array *\/<\/span>\r\n    qsort( fruit, size, sizeof(char *), compare);\r\n\r\n    <span class=\"comments\">\/* locate a value *\/<\/span>\r\n    r = bsearch( &amp;key, fruit, size, sizeof(char *), compare );\r\n    if( r!=NULL )\r\n        printf(\"Key %s found!\\n\",*r);\r\n    else\r\n        printf(\"Key %s not found.\\n\",key);\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The program&#8217;s output:<\/p>\n<p><code>Fruit: banana<br \/>\nKey banana found!<\/code><\/p>\n<p>Just as with sorting complex data, the tricky part is to properly code the <em>compare()<\/em> function. For <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6788\">next week&#8217;s Lesson<\/a>, I apply this insanity to sorting and searching an array of structures.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The deal with finding strings is that darned double-asterisk pointer notation! <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6779\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6779","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6779","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6779"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6779\/revisions"}],"predecessor-version":[{"id":6827,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6779\/revisions\/6827"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6779"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6779"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6779"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}