{"id":7635,"date":"2026-06-20T00:01:09","date_gmt":"2026-06-20T07:01:09","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7635"},"modified":"2026-06-13T10:38:24","modified_gmt":"2026-06-13T17:38:24","slug":"ctype-function-ispunct","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7635","title":{"rendered":"Ctype Function: <em>ispunct()<\/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 \/>\nFor the ctype <em>ispunct()<\/em> function, the goal is to understand that &#8220;punct&#8221; is short for punctuation and not puncture. To put this function to use you need to know what the library considers to be an ASCII punctuation character. It&#8217;s yet another step forward in my ongoing exploration of the <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7542\">ctype functions<\/a>.<br \/>\n<!--more--><br \/>\nAccording to the <em>ispunct()<\/em> function, the following ASCII characters are not considered punctuation:<\/p>\n<ul>\n<li>All control codes<\/li>\n<li>The space<\/li>\n<li>Numbers<\/li>\n<li>Uppercase letters<\/li>\n<li>Lowercase letters<\/li>\n<li>The DEL character (code 127)<\/li>\n<\/ul>\n<p>The following code uses the <em>ispunct()<\/em> function to sort out the lot of ASCII characters, from zero through 127 (the full ASCII code range):<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_06_20-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2026_06_20-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;ctype.h&gt;\r\n\r\n<span class=\"comments\">\/* output the wide ASCII character\r\n   specifically the control codes *\/<\/span>\r\nvoid outwide(int c)\r\n{\r\n    if( iscntrl(c) )\r\n    {\r\n        if( c==127 )\r\n            putwchar(9249);    <span class=\"comments\">\/* DEL *\/<\/span>\r\n        else\r\n            <span class=\"comments\">\/* 9216 = control code chars *\/<\/span>\r\n            putwchar(c+9216);\r\n    }\r\n    else\r\n    {\r\n        putwchar(c);\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    int ch;\r\n\r\n    <span class=\"comments\">\/* set the locale for wide characters *\/<\/span>\r\n    setlocale(LC_ALL,\"\");\r\n\r\n    wprintf(L\"Punctuation characters:\\n\");\r\n    <span class=\"comments\">\/* ASCII range *\/<\/span>\r\n    for( ch=0; ch&lt;=127; ch++ )\r\n        if( ispunct(ch) )\r\n            outwide(ch);\r\n    putwchar(L'\\n');\r\n\r\n    wprintf(L\"Not punctuation characters:\\n\");\r\n    <span class=\"comments\">\/* ASCII range *\/<\/span>\r\n    for( ch=0; ch&lt;=127; ch++ )\r\n        if( !ispunct(ch) )\r\n            outwide(ch);\r\n    putwchar(L'\\n');\r\n\r\n    return 0;\r\n}<\/pre>\n<p>I wrote the <em>outwide(<\/em>) function to avoid some repetition in the <em>main()<\/em> function. Its job is to output the wide character versions of the control codes (ASCII zero through 31) as well as the DEL (code 127) as appropriate Unicode values.<\/p>\n<p>The <em>main()<\/em> function contains two <em>for<\/em> loops. Each one uses the <em>ispunct()<\/em> function to test the value of ASCII code <code>ch<\/code>. The first loop outputs only what are considered to be punctuation characters. The second <em>for<\/em> loop outputs all the non-punctuation characters, which includes all the control codes as well as the DEL.<\/p>\n<p>Here is sample output:<\/p>\n<pre>Punctuation characters:\r\n!\"#$%&'()*+,-.\/:;<=>?@[\\]^_`{|}~\r\nNot punctuation characters:\r\n\u2400\u2401\u2402\u2403\u2404\u2405\u2406\u2407\u2408\u2409\u240a\u240b\u240c\u240d\u240e\u240f\u2410\u2411\u2412\u2413\u2414\u2415\u2416\u2417\u2418\u2419\u241a\u241b\u241c\u241d\u241e\u241f 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\u2421<\/pre>\n<p>In the following code, I&#8217;ve written my own <em>ispunct()<\/em> function. I also borrowed the <em>iscntrl()<\/em> function from <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7629\">last week&#8217;s Lesson<\/a>:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_06_20-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2026_06_20-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;stdbool.h&gt;\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\n<span class=\"comments\">\/* is the character \"punctuation\"? *\/<\/span>\r\nint ispunct(int c)\r\n{\r\n    <span class=\"comments\">\/* eliminate control codes &amp; space *\/<\/span>\r\n    if( c&gt;=0 &amp;&amp; c&lt;=' ')\r\n        return false;\r\n    <span class=\"comments\">\/* eliminate numbers\/digits *\/<\/span>\r\n    if( c&gt;='0' &amp;&amp; c&lt;='9' )\r\n        return false;\r\n    <span class=\"comments\">\/* eliminate uppercase *\/<\/span>\r\n    if( c&gt;='A' &amp;&amp; c&lt;='Z' )\r\n        return false;\r\n    <span class=\"comments\">\/* eliminate lowercase *\/<\/span>\r\n    if( c&gt;='a' &amp;&amp; c&lt;='z' )\r\n        return false;\r\n    <span class=\"comments\">\/* eliminate DEL *\/<\/span>\r\n    if( c==127 )\r\n        return false;\r\n\r\n    return true;\r\n}\r\n\r\n<span class=\"comments\">\/* output the wide ASCII character\r\n   specifically the control codes *\/<\/span>\r\nvoid outwide(int c)\r\n{\r\n    if( iscntrl(c) )\r\n    {\r\n        if( c==127 )\r\n            putwchar(9249);    <span class=\"comments\">\/* DEL *\/<\/span>\r\n        else\r\n            <span class=\"comments\">\/* 9216 = control code chars *\/<\/span>\r\n            putwchar(c+9216);\r\n    }\r\n    else\r\n    {\r\n        putwchar(c);\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    int ch;\r\n\r\n    <span class=\"comments\">\/* set the locale for wide characters *\/<\/span>\r\n    setlocale(LC_ALL,\"\");\r\n\r\n    wprintf(L\"Punctuation characters:\\n\");\r\n    <span class=\"comments\">\/* ASCII range *\/<\/span>\r\n    for( ch=0; ch&lt;=127; ch++ )\r\n        if( ispunct(ch) )\r\n            outwide(ch);\r\n    putwchar(L'\\n');\r\n\r\n    wprintf(L\"Not punctuation characters:\\n\");\r\n    <span class=\"comments\">\/* ASCII range *\/<\/span>\r\n    for( ch=0; ch&lt;=127; ch++ )\r\n        if( !ispunct(ch) )\r\n            outwide(ch);\r\n    putwchar(L'\\n');\r\n\r\n    return 0;\r\n}<\/pre>\n<p>My <em>ispunct()<\/em> function contains a towering series of <em>if<\/em> conditions, each of which weeds out the non-punctuation characters as listed at the start of this post. I could have also written a <em>switch-case<\/em> structure to list the 32 characters that the <em>ispunct()<\/em> function qualifies as punctuation. I could have also added the isalnum() function (<a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7585\">my own version<\/a>) to help fish out the letters and numbers. Anyway, you get the idea.<\/p>\n<p>For next week&#8217;s Lesson, I wrap up this series on the ctype functions with the final one: <em>isxdigit()<\/em>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The <em>ispunct<\/em> function identifies ASCII characters classified as punctuation, which covers more ground than you may first think. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7635\">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-7635","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\/7635","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=7635"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7635\/revisions"}],"predecessor-version":[{"id":7651,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7635\/revisions\/7651"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}