{"id":7596,"date":"2026-05-30T00:01:44","date_gmt":"2026-05-30T07:01:44","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7596"},"modified":"2026-05-23T11:38:21","modified_gmt":"2026-05-23T18:38:21","slug":"ctype-functions-isgraph-and-isprint","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7596","title":{"rendered":"Ctype Functions: <em>isgraph()<\/em> and <em>isprint()<\/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 \/>\nTwo very similar ctype functions are <em>isgraph()<\/em> and <em>isprint()<\/em>. Only one character separates the two functions. And the <em>isgraph()<\/em> function has nothing to do with graphics. These are the topics for this week&#8217;s Lesson as I continue my exploration of the <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7542\">ctype functions<\/a>.<br \/>\n<!--more--><br \/>\nAs a budding C programmer, I thought the <em>isgraph()<\/em> function returns TRUE for characters that are &#8220;graphical&#8221; in nature, such as the <code>|<\/code> and <code>-<\/code> characters.<\/p>\n<p>WRONG.<\/p>\n<p>The <em>isgraph()<\/em> function returns TRUE for any printable character &mdash; except for a space. This range excludes the DEL character, the blank at ASCII code 127.<\/p>\n<p>The <em>isprint()<\/em> function returns TRUE for all printable ASCII characters, including the space but not the DEL. I suppose the space &#8220;prints&#8221; in the way that is occupies the same portion of the space-time continuum as other characters, just minus the ink. DEL is often interpreted as a destructive backspace (backup and erase), though this behavior is inconsistent. Both functions return FALSE for DEL.<\/p>\n<p>Here&#8217;s some sample code:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_05_30-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2026_05_30-Lesson-a.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 main()\r\n{\r\n    char string[] = \"Nothing beats knowing the ASCII codes!\\n\";\r\n    char *s;\r\n\r\n    <span class=\"comments\">\/* output isgraph() test *\/<\/span>\r\n    puts(\"isgraph()\");\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        putchar(*s);\r\n        s++;\r\n    }\r\n    <span class=\"comments\">\/* testing output *\/<\/span>\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        if( isgraph(*s) )\r\n            putchar('^');\r\n        else\r\n            putchar(' ');\r\n        s++;\r\n    }\r\n    putchar('\\n');\r\n\r\n    <span class=\"comments\">\/* output isprint() test *\/<\/span>\r\n    puts(\"isprint()\");\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        putchar(*s);\r\n        s++;\r\n    }\r\n    <span class=\"comments\">\/* testing output *\/<\/span>\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        if( isprint(*s) )\r\n            putchar('^');\r\n        else\r\n            putchar(' ');\r\n        s++;\r\n    }\r\n    putchar('\\n');\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The code churns through <code>string[]<\/code>, examining each character by applying the <em>isgraph()<\/em> and <em>isprint()<\/em> ctype functions.<\/p>\n<p>For each function, the string is processed twice. First, a <em>while<\/em> loop outputs the string front-to-back. Second, each character is run through the ctype function; a caret is output to indicate which characters pass the function&#8217;s test, as shown in this sample run:<\/p>\n<pre>isgraph()\r\nNothing beats knowing the ASCII codes!\r\n^^^^^^^ ^^^^^ ^^^^^^^ ^^^ ^^^^^ ^^^^^^\r\nisprint()\r\nNothing beats knowing the ASCII codes!\r\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<\/pre>\n<p>For the <em>isgraph()<\/em> function, spaces fail the test; this is the only printable character not accepted by the function.<\/p>\n<p>For the <em>isprint()<\/em> function, all printable ASCII characters pass the test, including the space.<\/p>\n<p>Emulating these functions requires a test to determine whether the ASCII code is in the range of space (code 32 or 0x20) through tilde (<code>'~'<\/code> or 0x7E). Remember that the DEL character returns FALSE for both functions, so I don&#8217;t include it in this range.<\/p>\n<p>For the <em>isprint()<\/em> function, the result is TRUE for all characters in the given range. For the <em>isgraph()<\/em> function, the results are TRUE, save for the space character. For my emulation, I use the <em>isprint()<\/em> function within my <em>isgraph()<\/em> function to help make this distinction:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_05_30-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2026_05_30-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\n#define TRUE 1\r\n#define FALSE 0\r\n\r\nint isprint(int c)\r\n{\r\n    if( c&gt;=' ' &amp;&amp; c&lt;='~' )\r\n        return TRUE;\r\n    else\r\n        return FALSE;\r\n}\r\n\r\nint isgraph(int c)\r\n{\r\n    if( isprint(c) &amp;&amp; c!=' ' )\r\n        return TRUE;\r\n    else\r\n        return FALSE;\r\n}\r\n\r\nint main()\r\n{\r\n    char string[] = \"Nothing beats knowing the ASCII codes!\\n\";\r\n    char *s;\r\n\r\n    <span class=\"comments\">\/* output isgraph() test *\/<\/span>\r\n    puts(\"isgraph()\");\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        putchar(*s);\r\n        s++;\r\n    }\r\n    <span class=\"comments\">\/* testing output *\/<\/span>\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        if( isgraph(*s) )\r\n            putchar('^');\r\n        else\r\n            putchar(' ');\r\n        s++;\r\n    }\r\n    putchar('\\n');\r\n\r\n    <span class=\"comments\">\/* output isprint() test *\/<\/span>\r\n    puts(\"isprint()\");\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        putchar(*s);\r\n        s++;\r\n    }\r\n    <span class=\"comments\">\/* testing output *\/<\/span>\r\n    s = string;\r\n    while( *s != '\\0' )\r\n    {\r\n        if( isprint(*s) )\r\n            putchar('^');\r\n        else\r\n            putchar(' ');\r\n        s++;\r\n    }\r\n    putchar('\\n');\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The <em>isprint()<\/em> function returns TRUE when ASCII character <code>c<\/code> is in the range of <code>' '<\/code> (space) through <code>'~'<\/code>. The DEL (code 127 or 0x7F) is excluded.<\/p>\n<p>The <em>isgraph()<\/em> function uses the <em>isprint()<\/em> function in its if comparison, but ensures that character <code>c<\/code> is not the space. If so, the function returns TRUE. The space character forces the function to return FALSE.<\/p>\n<p>The program&#8217;s output is the same as for the first example.<\/p>\n<p>These two functions are weird. I assume that some reason exists why <em>isprint()<\/em> classifies the space as printable but <code>isgraph()<\/code> refuses to recognize it as &#8220;graphical.&#8221; This difference is probably due to some historical or otherwise relevant reason.<\/p>\n<p>In next week&#8217;s Lesson I cover the <em>isblank()<\/em> and <em>isspace()<\/em> ctype functions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Only a single character matters when comparing these two, similar ctype functions. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7596\">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-7596","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\/7596","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=7596"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7596\/revisions"}],"predecessor-version":[{"id":7617,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7596\/revisions\/7617"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}