{"id":1359,"date":"2015-05-16T00:01:15","date_gmt":"2015-05-16T07:01:15","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=1359"},"modified":"2015-05-09T08:03:14","modified_gmt":"2015-05-09T15:03:14","slug":"build-your-own-strcasestr-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=1359","title":{"rendered":"Build Your Own <em>strcasestr()<\/em> Function"},"content":{"rendered":"<p>I was a bit surprised the other day. I&#8217;d written code on my Macintosh and tried to run it on the PC. Because I usually write generic stuff, I figured that the code would compile and run on both systems. But it didn&#8217;t compile.<br \/>\n<!--more--><br \/>\nThe culprit was a function called <em>strcasestr()<\/em>. It&#8217;s a cousin to the standard C library string comparison function, <em>strstr()<\/em>. The word <em>case<\/em> sandwiched inside means that the strings are compared in a case-insensitive way. Otherwise, both functions are identical.<\/p>\n<p>So I set out to concoct my own rendition of <em>strcasestr()<\/em>.<\/p>\n<p>First, here&#8217;s sample code that prompts the user to type two strings. The strings are compared by using the <em>strstr()<\/em> function:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\nint main()\r\n{\r\n    char first[32],second[32];\r\n\r\n<span class=\"comments\">\/* Fetch strings *\/<\/span>\r\n    puts(\"String comparison\");\r\n    printf(\"First string: \");\r\n    fgets(first,32,stdin);\r\n    printf(\"Second string: \");\r\n    fgets(second,32,stdin);\r\n\r\n<span class=\"comments\">\/* Compare *\/<\/span>\r\n    if( strcmp(first,second)==0 )\r\n        puts(\"Strings match\");\r\n    else\r\n        puts(\"Strings don't match\");\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Here&#8217;s a sample run, where you can see how the same word doesn&#8217;t match when the letters are uppercase or lowercase:<\/p>\n<pre><code>String comparison\r\nFirst string: <span style=\"color:black; font-weight:bold\">this<\/span>\r\nSecond string: <span style=\"color:black; font-weight:bold\">THIS<\/span>\r\nStrings don't match<\/code><\/pre>\n<p>To fix this problem, I crafted a new function, <em>case_compare()<\/em>. I wanted it to mimic the behavior of <em>strstr()<\/em>: Values returned are positive, negative, or zero depending on how the strings compare. Not knowing how <em>strstr()<\/em> operates internally, I chose to use a single character comparison, shown in the following code:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;ctype.h&gt;\r\n\r\nint case_compare(char *a, char *b)\r\n{\r\n    char c;\r\n\r\n    while(*a)\r\n    {\r\n        c = toupper(*a) - toupper(*b);\r\n        if( c != 0 )\r\n            return(c);\r\n        a++;\r\n        b++;\r\n    }\r\n    return(c);\r\n}\r\n\r\nint main()\r\n{\r\n    char first[32],second[32];\r\n\r\n<span class=\"comments\">\/* Fetch strings *\/<\/span>\r\n    puts(\"String comparison\");\r\n    printf(\"First string: \");\r\n    fgets(first,32,stdin);\r\n    printf(\"Second string: \");\r\n    fgets(second,32,stdin);\r\n\r\n<span class=\"comments\">\/* Compare *\/<\/span>\r\n    if( case_compare(first,second)==0 )\r\n        puts(\"Strings match\");\r\n    else\r\n        puts(\"Strings don't match\");\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>case_compare()<\/em> function&#8217;s <em>while<\/em> loop at Line 8 plows through string <code>a<\/code> with string <code>b<\/code> along for the ride. At each position, character <code>*a<\/code> is compared with character <code>*b<\/code>, but only when the <em>toupper()<\/em> function has converted both to uppercase (Line 10).<\/p>\n<p>When the result in variable <code>c<\/code> is zero, then the characters match (case insensitive). If not, the <em>if<\/em> test at Line 11 catches the mismatch and the comparison value (positive or negative) is returned in Line 12. Otherwise, both string pointers are incremented and the comparison continues.<\/p>\n<p>The final <em>return<\/em> statement at Line 16 passes the value of variable <code>c<\/code> back to the calling function, which is zero when both strings match. That mimics the behavior of the <em>strstr()<\/em> function, although I&#8217;m not certain exactly how that function works internally.<\/p>\n<p>The bottom line is that my <em>case_compare()<\/em> function works on any platform, whether the library offers <em>strcasestr()<\/em> or not. That&#8217;s the result I was looking for.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Not every C language library features a case-insensitive comparison function. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1359\">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-1359","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\/1359","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=1359"}],"version-history":[{"count":7,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1359\/revisions"}],"predecessor-version":[{"id":1376,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1359\/revisions\/1376"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1359"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1359"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}