{"id":4404,"date":"2020-10-17T00:01:35","date_gmt":"2020-10-17T07:01:35","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4404"},"modified":"2020-10-17T08:32:02","modified_gmt":"2020-10-17T15:32:02","slug":"string-versions-of-ctype-functions","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4404","title":{"rendered":"String Versions of ctype Functions"},"content":{"rendered":"<p>The ctype functions are marvelous for single character manipulation and testing. Often, however, the functions appear in a loop so that they can be applied to an entire string. So why not write a string-based ctype function? Of course, that&#8217;s what I did.<br \/>\n<!--more--><br \/>\nEach function works with a sample string, one that contains uppercase and lowercase letters, as well as a smattering of symbols:<\/p>\n<p><code>char sample[] = \"This is Sample String #1 TEXT\\n\";<\/code><\/p>\n<p>My goal was to apply three separate functions to this string:<\/p>\n<ul>\n<li><em>str_tolower()<\/em> to convert characters in the string to lowercase.<\/li>\n<li><em>str_toupper()<\/em> to convert characters in the string to uppercase.<\/li>\n<li><em>str_toinverse()<\/em> to switch lowercase characters to uppercase and vice-versa.<\/li>\n<\/ul>\n<p>In all instances, I sought not to use any ctype functions, but manipulate the characters directly. Here is my code for the <em>str_tolower()<\/em> function:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_10_17-Lesson-a.c\" rel=\"noopener noreferrer\" target=\"_blank\">2020_10_17-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nvoid str_tolower(char *s)\r\n{\r\n    while(*s)\r\n    {\r\n        if( *s&gt;='A' &amp;&amp; *s&lt;='Z' )\r\n            *s |= 32;\r\n        s++;\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    char sample[] = \"This is Sample String #1 TEXT\\n\";\r\n\r\n    printf(\"Before:\\n%s\",sample);\r\n    str_tolower(sample);\r\n    printf(\"After:\\n%s\",sample);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>At Line 7, an <em>if<\/em> test determines whether the character is in the uppercase range. If so, a bitwise OR is performed to set the bit that converts the character to uppercase: <code>*s |= 32;<\/code>. (32 decimal is 0x20 hex.) <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1017\">Click here<\/a> to review the Lesson from 2014 where I discuss this trick. Figure 1 shows a nifty graphic that explains how it works in detail.<\/p>\n<div id=\"attachment_1028\" style=\"width: 460px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1028\" src=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2014\/10\/1025-figure2.png\" alt=\"\" width=\"450\" height=\"245\" class=\"size-full wp-image-1028\" srcset=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2014\/10\/1025-figure2.png 450w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2014\/10\/1025-figure2-300x163.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><p id=\"caption-attachment-1028\" class=\"wp-caption-text\">Figure 1. Using bit manipulation to convert &#8216;A&#8217; into &#8216;a&#8217;.<\/p><\/div>\n<p>Here is sample output:<\/p>\n<p><code>Before:<br \/>\nThis is Sample String #1 TEXT<br \/>\nAfter:<br \/>\nthis is sample string #1 text<\/code><\/p>\n<p>The second function, <em>str_toupper()<\/em>, works similarly, though the <em>if<\/em> test at Line 7 checks for lowercase letters and the bitwise operation at Line 8 masks a bit to make the letter uppercase:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_10_17-Lesson-b.c\" rel=\"noopener noreferrer\" target=\"_blank\">2020_10_17-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nvoid str_toupper(char *s)\r\n{\r\n    while(*s)\r\n    {\r\n        if( *s&gt;='a' &amp;&amp; *s&lt;='z' )\r\n            *s &amp;= 223;\r\n        s++;\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    char sample[] = \"This is Sample String #1 TEXT\\n\";\r\n\r\n    printf(\"Before:\\n%s\",sample);\r\n    str_toupper(sample);\r\n    printf(\"After:\\n%s\",sample);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Figure 2 is an illustration from my ancient blog post, showing how the bitwise AND operator makes a lowercase character uppercase:<\/p>\n<div id=\"attachment_1027\" style=\"width: 460px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1027\" src=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2014\/10\/1025-figure1.png\" alt=\"\" width=\"450\" height=\"237\" class=\"size-full wp-image-1027\" srcset=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2014\/10\/1025-figure1.png 450w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2014\/10\/1025-figure1-300x158.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><p id=\"caption-attachment-1027\" class=\"wp-caption-text\">Figure 2. Using the logical &amp; operator to convert from &#8216;a&#8217; to &#8216;A&#8217;.<\/p><\/div>\n<p>Here is the code&#8217;s output:<\/p>\n<p><code>Before:<br \/>\nThis is Sample String #1 TEXT<br \/>\nAfter:<br \/>\nTHIS IS SAMPLE STRING #1 TEXT<\/code><\/p>\n<p>The final function, <em>str_inverse()<\/em>, has no ctype counterpart in the standard C library. In the function, I test for uppercase letters and convert them to lowercase and vice-versa. The code includes statements from the two other functions:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_10_17-Lesson-c.c\" rel=\"noopener noreferrer\" target=\"_blank\">2020_10_17-Lesson-c.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nvoid str_toinverse(char *s)\r\n{\r\n    while(*s)\r\n    {\r\n        if( *s&gt;='A' &amp;&amp; *s&lt;='Z' )\r\n        {\r\n            *s |= 32;\r\n            s++;\r\n        }\r\n        else if( *s&gt;='a' &amp;&amp; *s&lt;='z' )\r\n        {\r\n            *s &amp;= 223;\r\n            s++;\r\n        }\r\n        else\r\n            s++;\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    char sample[] = \"This is Sample String #1 TEXT\\n\";\r\n\r\n    printf(\"Before:\\n%s\",sample);\r\n    str_toinverse(sample);\r\n    printf(\"After:\\n%s\",sample);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>If the character is uppercase (Line 7), the bitwise OR operator makes it lowercase at Line 9. If the character is lowercase (Line 12), the bitwise AND operator makes it uppercase at line 14. Each part of the <em>if-else if-else<\/em> structure contains the statement s++;. This ensures that the entire string is processed regardless of which character is encountered. Here&#8217;s the output:<\/p>\n<p><code>Before:<br \/>\nThis is Sample String #1 TEXT<br \/>\nAfter:<br \/>\ntHIS IS sAMPLE sTRING #1 text<\/code><\/p>\n<p>In each example, a pointer is passed. This choice allows the string to be manipulated directly; nothing needs be returned. The address in variable <code>s<\/code> can be manipulated in the functions because doing so doesn&#8217;t alter the address outside the function. This flexibility is yet another way pointers can be useful.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Why not apply functions like <em>toupper()<\/em> and <em>tolower()<\/em> to an entire string, not just a single character? <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4404\">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-4404","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\/4404","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=4404"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4404\/revisions"}],"predecessor-version":[{"id":4417,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4404\/revisions\/4417"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}