{"id":7629,"date":"2026-06-13T00:01:09","date_gmt":"2026-06-13T07:01:09","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7629"},"modified":"2026-06-06T15:21:47","modified_gmt":"2026-06-06T22:21:47","slug":"ctype-functions-isascii-and-iscntrl","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7629","title":{"rendered":"Ctype Functions: <em>isascii()<\/em> and <em>iscntrl()<\/em>"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/05\/ctype.png\" alt=\"\" width=\"400\" height=\"138\" class=\"alignnone size-full wp-image-7590\" srcset=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/05\/ctype.png 400w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/05\/ctype-300x104.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><br \/>\nI almost believe these two functions to be useless, but they do play an important role in the ctype pantheon: <em>isascii()<\/em> determines whether an integer value is an ASCII character, and <em>iscntrl()<\/em> lets the program know further whether an integer value is also an ASCII control code. This pair adds to my continuing exploration of the <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7542\">ctype functions<\/a>.<br \/>\n<!--more--><br \/>\nHere are the specific definitions:<\/p>\n<p>The <em>isascii()<\/em> function returns TRUE when the value of its integer argument is in the range of zero through 127, the ASCII code values. (ASCII represents <em>unsigned char<\/em> values, but the function&#8217;s argument is an <em>int<\/em> data type.)<\/p>\n<p>The <em>iscntrl()<\/em> function returns TRUE when the value of its integer argument is in the range of ASCII codes zero through 31 plus the DEL character, code 127. These are all unprintable characters, though some affect the cursor&#8217;s position.<\/p>\n<p>To test these two functions, I wrote code that generates 20 random values in the range of zero through 255. For each value generated, a line is output showing its decimal and hexadecimal values, as well as its Unicode character representation. Then the code explains whether the value is ASCII, non-ASCII, or a control code. It&#8217;s assumed that all control codes are ASCII values by definition.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_06_13-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2026_06_13-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;locale.h&gt;\r\n#include &lt;wchar.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;time.h&gt;\r\n#include &lt;ctype.h&gt;\r\n\r\nint main()\r\n{\r\n    int x,r;\r\n\r\n    <span class=\"comments\">\/* seed the randomizer *\/<\/span>\r\n    srand( (unsigned)time(NULL) );\r\n\r\n    <span class=\"comments\">\/* set the locale for wide characters *\/<\/span>\r\n    setlocale(LC_ALL,\"\");\r\n\r\n    <span class=\"comments\">\/* generate and evaluate 20 random chars *\/<\/span>\r\n    for( x=0; x&lt;20; x++ )\r\n    {\r\n        r = rand() % 0xFF;    <span class=\"comments\">\/* char range *\/<\/span>\r\n        wprintf(L\"%03d %02X \",r,r);\r\n        if( isascii(r) )\r\n        {\r\n            if( iscntrl(r) )\r\n            {\r\n                <span class=\"comments\">\/* call out DEL *\/<\/span>\r\n                if( r==127 )\r\n                    wprintf(L\"%lc - control code\",9249);\r\n                <span class=\"comments\">\/* other Unicode ctrl chars *\/<\/span>\r\n                else\r\n                    wprintf(L\"%lc - control code\",r+9216);\r\n            }\r\n            else\r\n                wprintf(L\"%lc - ASCII\",r);\r\n        }\r\n        else\r\n        {\r\n            wprintf(L\"%lc - non-ASCII\",0xB7);    <span class=\"comments\">\/* B7 = dot *\/<\/span>\r\n        }\r\n        putwchar(L'\\n');\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Testing for ASCII and control code values takes place in the <em>for<\/em> loop. An <em>if-else<\/em> decision determines whether the character is ASCII. If not (<em>else<\/em>), a dot character is output along with the text &#8220;non-ASCII.&#8221; When an ASCII character is found, the <em>iscntrl()<\/em> function checks for a control code value. If true, the control code&#8217;s Unicode character is output, otherwise the ASCII character is output.<\/p>\n<p>Here is a sample run:<\/p>\n<pre>173 AD \u00b7 - non-ASCII\r\n054 36 6 - ASCII\r\n038 26 & - ASCII\r\n038 26 & - ASCII\r\n218 DA \u00b7 - non-ASCII\r\n065 41 A - ASCII\r\n218 DA \u00b7 - non-ASCII\r\n247 F7 \u00b7 - non-ASCII\r\n097 61 a - ASCII\r\n160 A0 \u00b7 - non-ASCII\r\n075 4B K - ASCII\r\n072 48 H - ASCII\r\n012 0C \u240c - control code\r\n122 7A z - ASCII\r\n070 46 F - ASCII\r\n035 23 # - ASCII\r\n164 A4 \u00b7 - non-ASCII\r\n157 9D \u00b7 - non-ASCII\r\n002 02 \u2402 - control code\r\n110 6E n - ASCII<\/pre>\n<p>Emulating these functions requires a range test. For ASCII characters, the integer range is from zero through 127; for control codes the range is from zero through 31. My <em>isascii()<\/em> and <em>iscntrl()<\/em> functions use this range and return values <em>true<\/em> or <em>false<\/em> accordingly:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_06_13-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2026_06_13-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;locale.h&gt;\r\n#include &lt;wchar.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;time.h&gt;\r\n#include &lt;stdbool.h&gt;\r\n\r\n<span class=\"comments\">\/* is the character ASCII? *\/<\/span>\r\nint isascii(int c)\r\n{\r\n    if( c&gt;=0 &amp;&amp; c&lt;=127 )\r\n        return true;\r\n    else\r\n        return false;\r\n}\r\n\r\n<span class=\"comments\">\/* is the character a control code? *\/<\/span>\r\nint iscntrl(int c)\r\n{\r\n    if( (c&gt;=0 &amp;&amp; c&lt;=31) || c==127 )\r\n        return true;\r\n    else\r\n        return false;\r\n}\r\n\r\nint main()\r\n{\r\n    int x,r;\r\n\r\n    <span class=\"comments\">\/* seed the randomizer *\/<\/span>\r\n    srand( (unsigned)time(NULL) );\r\n\r\n    <span class=\"comments\">\/* set the locale for wide characters *\/<\/span>\r\n    setlocale(LC_ALL,\"\");\r\n\r\n    <span class=\"comments\">\/* generate and evaluate 20 random chars *\/<\/span>\r\n    for( x=0; x&lt;20; x++ )\r\n    {\r\n        r = rand() % 0xFF;    <span class=\"comments\">\/* char range *\/<\/span>\r\n        wprintf(L\"%03d %02X \",r,r);\r\n        if( isascii(r) )\r\n        {\r\n            if( iscntrl(r) )\r\n            {\r\n                <span class=\"comments\">\/* call out DEL *\/<\/span>\r\n                if( r==127 )\r\n                    wprintf(L\"%lc - control code\",9249);\r\n                <span class=\"comments\">\/* other Unicode ctrl chars *\/<\/span>\r\n                else\r\n                    wprintf(L\"%lc - control code\",r+9216);\r\n            }\r\n            else\r\n                wprintf(L\"%lc - ASCII\",r);\r\n        }\r\n        else\r\n        {\r\n            wprintf(L\"%lc - non-ASCII\",0xB7);    <span class=\"comments\">\/* B7 = dot *\/<\/span>\r\n        }\r\n        putwchar(L'\\n');\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The program&#8217;s output is the same.<\/p>\n<p>These functions are necessary when processing data to look for and weed out ASCII characters as well as control codes. Even so, I don&#8217;t think I&#8217;ve ever used them. I just use the same range check as shown in my functions (above).<\/p>\n<p>For next week&#8217;s Lesson, I cover the ctype function <em>ispunct()<\/em>, which is not the same is <em>ispunked()<\/em>, which isn&#8217;t a C language function at all (though it can be if you want to code it).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>These functions seem unnecessary, but do play a role in evaluating a <em>char<\/em> value. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7629\">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-7629","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\/7629","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=7629"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7629\/revisions"}],"predecessor-version":[{"id":7637,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7629\/revisions\/7637"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7629"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7629"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7629"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}