{"id":5160,"date":"2022-01-22T00:01:14","date_gmt":"2022-01-22T08:01:14","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5160"},"modified":"2022-01-15T09:27:14","modified_gmt":"2022-01-15T17:27:14","slug":"my-own-strcasecmp-function-round-three","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5160","title":{"rendered":"My Own <em>strcasecmp()<\/em> Function &#8211; Round Three"},"content":{"rendered":"<p>The <em>strcasecmp()<\/em> function isn&#8217;t part of the standard C library, though many compilers feature it. As having the function is handy, I wrote about crafting your own version <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3863\">back in 2019<\/a>. Alas, that implementation is flawed.<br \/>\n<!--more--><br \/>\nThe first flaw was pointed out to me by Professor Dr. Greg Byrd of North Carolina State University. He noted that the function doesn&#8217;t necessarily return the difference between mismatched characters. Some compilers instead return -1, 0, or 1. In fact, the <em>strcasecmp()<\/em> <em>man<\/em> page, as well as the <em>man<\/em> page for <em>strcmp()<\/em>, claim that the return value is less than, greater than, or equal to zero.<\/p>\n<p>My <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4657\">first update to the code<\/a> accounted for the return value, as noted by Dr. Byrd. I added a function <em>sign()<\/em>, which returns -1, 0, or 1 based on the value of a passed integer. Even with this update, however, <a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2021_03_13-Lesson.c\">the code<\/a> remains flawed.<\/p>\n<p>I didn&#8217;t discover another issue with my <em>strcasecmp()<\/em> function until I used it to compare two similar strings, one longer than the other:<\/p>\n<p><code>\"I drink co\"<br \/>\n\"I drink coffee and tea\"<\/code><\/p>\n<p>The program reports that both strings match. However, when I use the (non-standard) library function <em>strcasecmp()<\/em>, as well as the <em>strcmp()<\/em> function, the strings are reported as not matching.<\/p>\n<p>For reference, here is the <em>while<\/em> loop in my <em>strcasecmp()<\/em> function that compares strings, <code>s1<\/code> and <code>s2<\/code>:<\/p>\n<pre class=\"screen\">\r\noffset = 0;\r\nch = 0;\r\nwhile( *(s1+offset) != '\\0' )\r\n{\r\n    <span class=\"comments\">\/* check for end of s2 *\/<\/span>\r\n    if( *(s2+offset)=='\\0')\r\n        return( *(s1+offset) );\r\n\r\n    a = (unsigned)*(s1+offset);\r\n    b = (unsigned)*(s2+offset);\r\n    ch = toupper(a) - toupper(b);\r\n    if( ch&lt;0 || ch&gt;0 )\r\n        return( sign(ch) );\r\n    offset++;\r\n}<\/pre>\n<p>In the loop, you see both strings are tested for their terminating condition: <code>s1<\/code> in the <em>while<\/em> loop&#8217;s condition, then an <em>if<\/em> statement tests for the terminating null character in <code>s2<\/code>. This construction is wrong, as it doesn&#8217;t properly detect the end of the second string.<\/p>\n<p>The fix is easy: Place both comparisons as the <em>while<\/em> loop&#8217;s condition:<\/p>\n<p><code>while( *(s1+offset)!='\\0' || *(s2+offset)!='\\0' )<\/code><\/p>\n<p>I updated the code, as well as the testing statements to compare similar strings of different lengths. Here&#8217;s the output:<\/p>\n<p><code>I drink coffee v. I drink coffee = match<br \/>\nI drink coffee v. I DRINK COFFEE = match<br \/>\nI drink coffee v. I drink tea = no match<br \/>\nI drink coffee v. I drink co = no match<br \/>\nI drink coffee v. I drink coffee and tea = no match<\/code><\/p>\n<p>This flaw was discovered when I tried to use my own <em>strcasecmp()<\/em> function in the unique words series of programs back in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5113\">this Lesson<\/a> from earlier this month. My version of the <em>strcasecmp()<\/em> function incorrectly matched &#8220;to&#8221; and &#8220;too.&#8221; I&#8217;m embarrassed that my code didn&#8217;t work, but happy that I discovered the flaw and was able to fix the code with an update.<\/p>\n<p><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_01_22-Lesson.c\" rel=\"noopener\" target=\"_blank\">Click here<\/a> to view my fully updated code on Github. This third version is hopefully the final update.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I hope this time I finally get it right. I hope. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5160\">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-5160","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\/5160","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=5160"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5160\/revisions"}],"predecessor-version":[{"id":5174,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5160\/revisions\/5174"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}