{"id":4657,"date":"2021-03-13T00:01:53","date_gmt":"2021-03-13T08:01:53","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4657"},"modified":"2021-03-06T10:33:37","modified_gmt":"2021-03-06T18:33:37","slug":"an-update-to-my-strcasecmp-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4657","title":{"rendered":"An Update to My <em>strcasecmp()<\/em> Function"},"content":{"rendered":"<p>Many moons ago, I <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3863\">wrote about<\/a> the non-standard function, <em>strcasecmp()<\/em>. It works like the C library function <em>strcmp()<\/em>, though it ignores character case. Turns out my return value from the function isn&#8217;t exactly correct.<br \/>\n<!--more--><br \/>\nThe <em>man<\/em> page for <em>strcasecmp()<\/em> claims that the function returns &#8220;an integer greater than, equal     to, or less than 0, according as <code>s1<\/code> is lexicographically greater than, equal to, or less than s2<code> <\/code>after translation of each corresponding character to lower-case.&#8221; This is the same language used for the <em>strcmp()<\/em> function. But this behavior isn&#8217;t consistent across all C libraries.<\/p>\n<p>According to North Carolina State University Professor Dr. Greg Byrd, who emailed me on this topic, some compilers return 1, 0 or -1 and not the difference between the characters&#8217; code values. In my code, I used this comparison:<\/p>\n<p><code>ch = toupper(a) - toupper(b);<\/code><\/p>\n<p>This statement reflects the <em>man<\/em> page description quoted earlier: The value of variable <code>ch<\/code> is returned from the function: zero when the characters match, the difference between them otherwise. According to Dr. Byrd, however, non-GNU C compilers behave differently. This confusion trips up his students because they anticipate values 1, 0, or -1 and nothing larger.<\/p>\n<p>To address this inconsistency, yet maintain compatibility with the <em>man<\/em> page for (non-standard) function <em>strcasecmp()<\/em>, an update to the code is in order. Specifically, I chose to add my <em>sign()<\/em> function, which was part of this month&#8217;s Exercise (<a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4651\">solution link<\/a>).<\/p>\n<p>Here is the updated code, which includes a call to my <em>sign()<\/em> function:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2021_03_13-Lesson.c\" rel=\"noopener\" target=\"_blank\">2021_03_13-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;ctype.h&gt;\r\n\r\nint sign(int a)\r\n{\r\n    <span class=\"comments\">\/* value is negative *\/<\/span>\r\n    if( a&lt;0 ) return(-1);\r\n\r\n    <span class=\"comments\">\/* value is positive *\/<\/span>\r\n    if( a&gt;0 ) return(1);\r\n\r\n    <span class=\"comments\">\/* value is zero *\/<\/span>\r\n    return(0);\r\n}\r\n\r\nint strcasecmp(const char *s1, const char *s2)\r\n{\r\n    int offset,ch;\r\n    unsigned char a,b;\r\n\r\n    offset = 0;\r\n    ch = 0;\r\n    while( *(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    }\r\n\r\n    return( sign(ch) );\r\n}\r\n\r\nvoid test(const char *s1, const char *s2)\r\n{\r\n    printf(\"%s v. %s = \",s1,s2);\r\n    if( strcasecmp(s1,s2)==0 )\r\n        puts(\"match\");\r\n    else\r\n        puts(\"no match\");\r\n}\r\n\r\nint main()\r\n{\r\n    char string1[] = \"I drink coffee\";\r\n    char string2[] = \"I DRINK COFFEE\";\r\n    char string3[] = \"I drink tea\";\r\n\r\n    test(string1,string1);\r\n    test(string1,string2);\r\n    test(string1,string3);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>sign()<\/em> function is called from within the <em>strcasecmp()<\/em> function at Lines 33 and 37. The value returned, <code>ch<\/code> or the difference between individual characters in the strings passed, is interpreted as -1, 0, or 1. The difference between the characters is no longer returned, which is what Dr. Byrd suggested.<\/p>\n<p>The code still obeys the <em>man<\/em> page format; the value returned is positive, zero, or negative, though the values are restricted to 1, 0, and -1. Of course, the effect is that other coders who rely upon the return value to reflect the difference between specific characters will now be unable to do so. Still, the beauty of C is that you can always write your own function that behaves the way you want it to.<\/p>\n<p>Thanks again to Professor Byrd from North Carolina State University for pointing out my oversight.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The C library is often implemented inconsistently. A case in point is the <em>strcasecmp()<\/em> function. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4657\">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-4657","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\/4657","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=4657"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4657\/revisions"}],"predecessor-version":[{"id":4663,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4657\/revisions\/4663"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}