{"id":4341,"date":"2020-09-12T00:01:40","date_gmt":"2020-09-12T07:01:40","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4341"},"modified":"2025-05-28T20:48:55","modified_gmt":"2025-05-29T03:48:55","slug":"the-most-curious-aspect-of-the-scanf-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4341","title":{"rendered":"The Most Curious Aspect of the <em>scanf()<\/em> Function"},"content":{"rendered":"<p>It&#8217;s incorrect to say that the format string for the <em>printf()<\/em> function is identical to the one used in the <em>scanf()<\/em> function. Both are similar, but <em>scanf()<\/em> has one major difference.<br \/>\n<!--more--><br \/>\nFrom <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4335\">last week&#8217;s Lesson<\/a>, I showed how to use multiple placeholders in the <em>scanf()<\/em> input format string. In addition to those shared with the <em>printf()<\/em> function, <em>scanf()<\/em> features two additional placeholder characters: <code>%[...]<\/code> and <code>%[^...]<\/code>. These are input filters.<\/p>\n<p>The for <code>%[...]<\/code> filter, the <em>scanf()<\/em> function reads text input and captures only the characters specific in the placeholder (the ellipsis). The following code demonstrates:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_09_12-Lesson-a.c rel=\"noopener noreferrer\" target=\"_blank\"\">2020_09_12-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char buffer[32];\r\n\r\n    printf(\"Type: \");\r\n    scanf(\"%[ABC]\",buffer);\r\n    printf(\"Input: '%s'\\n\",buffer);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The format string in the statement at Line 8 directs the <em>scanf()<\/em> function to accept only characters <code>A<\/code>, <code>B<\/code>, and <code>C<\/code> as input. They can appear in any order, in any quantity, but only these characters. Anything else typed terminates the input string. Here are several sample runs:<\/p>\n<p><code>Type: ABC<br \/>\nInput: 'ABC'<\/code><\/p>\n<p><code>Type: BAC<br \/>\nInput: BAC<\/code><\/p>\n<p><code>Type: AAAAABBBBBCCCCC<br \/>\nInput: AAAAABBBBBCCCCC<\/code><\/p>\n<p><code>Type: ABCDABC<br \/>\nInput: ABC<\/code><\/p>\n<p>In the final example, character <code>D<\/code> is typed but it doesn&#8217;t appear in the bracketed list. So when it&#8217;s encountered the input stream terminates.<\/p>\n<p>Here&#8217;s a more practical example:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_09_12-Lesson-b.c rel=\"noopener noreferrer\" target=\"_blank\"\">2020_09_12-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char buffer[32];\r\n\r\n    printf(\"Type: \");\r\n    scanf(\"%[$1234567890.,]\",buffer);\r\n    printf(\"Input: '%s'\\n\",buffer);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The format string <code>\"%[$1234567890.,]\"<\/code> limits input to the characters specified. Here&#8217;s are sample runs:<\/p>\n<p><code>Type: $1,567,039.12<br \/>\nInput: '$1,567,039.12'<\/code><\/p>\n<p><code>Type: 100<br \/>\nInput: '100'<\/code><\/p>\n<p><code>Type: $1,000 dollars<br \/>\nInput: '$1,000'<\/code><\/p>\n<p>Of course, the code isn&#8217;t &#8220;practical&#8221; because the <em>scanf()<\/em> function can easily overflow. This admonition holds true for all of these formatting string tricks.<\/p>\n<p>The second version of this special placeholder is <code>$[^...]<\/code> where the <code>^<\/code> character acts as a logical NOT. The effect is that the input string is valid until one of the characters specified is encountered. Many coders use this trick to allow <em>scanf()<\/em> to input a line of text, as in:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_09_12-Lesson-c.c rel=\"noopener noreferrer\" target=\"_blank\"\">2020_09_12-Lesson-c.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char buffer[128];\r\n\r\n    printf(\"Type: \");\r\n    scanf(\"%[^\\n]\",buffer);\r\n    printf(\"'%s'\\n\",buffer);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The format string at Line 8 is <code>\"%[^\\n]\"<\/code>, which reads: Accept all characters except for the newline. Here&#8217;s a sample run:<\/p>\n<p><code>Type: This is a test<br \/>\n'This is a test'<\/code><\/p>\n<p>Effectively, <em>scanf()<\/em> can read strings in this format, though the strings can still overflow.<\/p>\n<p>The <code>[...]<\/code> and <code>[^...]<\/code> text filter placeholders find their way into many programming languages and scripting tools. They&#8217;re common meta-character filters, used to include or include characters. It&#8217;s rare that I&#8217;ve seen them used in C code, mostly because the <em>scanf()<\/em> function itself is weak.<\/p>\n<p>If you truly want valid input, I recommend that you code your own function or use an existing function like <em>fgets()<\/em> and heavily examine the input to ensure that it&#8217;s what the code needs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The format string for <em>printf()<\/em> and <em>scanf()<\/em> isn&#8217;t exactly identical, specifically with regards to two unusual placeholders. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4341\">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-4341","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\/4341","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=4341"}],"version-history":[{"count":9,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4341\/revisions"}],"predecessor-version":[{"id":7022,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4341\/revisions\/7022"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}