{"id":2183,"date":"2016-10-29T00:01:49","date_gmt":"2016-10-29T07:01:49","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=2183"},"modified":"2016-10-15T12:23:31","modified_gmt":"2016-10-15T19:23:31","slug":"a-scanf-string-trick","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=2183","title":{"rendered":"A <em>scanf()<\/em> String Trick"},"content":{"rendered":"<p>I&#8217;m not a fan of the <em>scanf()<\/em> function, despite how handy it can be. It&#8217;s a great teaching tool, but for a  program that accepts string input, you need to use <em>fgets()<\/em> instead. Still, <em>scanf()<\/em> can be used to read a string, providing that you know the whitespace requirements beforehand.<br \/>\n<!--more--><br \/>\nAs a review, the <em>scanf()<\/em> function fetches specific type of information from standard input. The format for desired input is specified as the function&#8217;s first argument, a string. That string typically contains a single placeholder character, such as <code>%d<\/code> for an <em>int<\/em> value.<\/p>\n<p>After the formatting string, <em>scanf()<\/em>&#8216;s second argument is pointer variable; the <code>&<\/code> operator is prefixed to the variable if it&#8217;s not already a pointer. The goal is to pass the variable&#8217;s address to the function so that the value fetched from standard input is stored in that variable.<\/p>\n<p>Here&#8217;s a sample:<\/p>\n<p><code>scanf(\"%c\",&ch);<\/code><\/p>\n<p>A single character, represented by <code>%c<\/code>, is fetched from the standard input stream and saved into <em>char<\/em> variable <code>ch<\/code>.<\/p>\n<p>What frustrates me about <em>scanf()<\/em> and strings is the function&#8217;s fixation with whitespace characters: At the sign of the first space, tab, or newline character, the function stops reading input. So <em>scanf()<\/em> isn&#8217;t a string-input function; it&#8217;s more of a word-input function.<\/p>\n<p>You can take advantage of <em>scanf()<\/em>&#8216;s word-input aspect to read multiple words in a string, but only when you&#8217;re certain of the exact number of words.<\/p>\n<p>As an example, the following program asks the user to type in their first, middle, and last names &mdash; three character chunks separated by whitespace:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char first[24], middle[24], last[24];\r\n\r\n    printf(\"Type your name (first middle last): \");\r\n    scanf(\"%23s\",first);\r\n    scanf(\"%23s\",middle);\r\n    scanf(\"%23s\",last);\r\n    printf(\"Glad to meet you, %s %s %s\\n\",\r\n            first,\r\n            middle,\r\n            last);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>I set the buffer size to 24 characters for each of the <em>char<\/em> arrays (strings). Further, the formatting string for the <em>scanf()<\/em> functions uses 23 to help truncate input. (The 24th character is the null, <code>\\0<\/code>, at the end of the string.) Here&#8217;s a sample run:<\/p>\n<pre><code>Type your name (first middle last): Arthur Templeton Grockmeister\r\nGlad to meet you, Arthur Templeton Grockmeister<\/code><\/pre>\n<p>The three <em>scanf()<\/em> functions read each work chunk from the input stream: The <em>scanf()<\/em> function at Line 8 stops reading after the first space. The next <em>scanf()<\/em> function at Line 9 stops after the second space. The final <em>scanf()<\/em> function (Line 10) stops at the newline character.<\/p>\n<p>If you type a name with more than 23 characters, input is cropped, thanks to the <code>%23s<\/code> string format placeholder:<\/p>\n<pre><code>Type your name (first middle last): Art T Grockalockfickafockameister\r\nGlad to meet you, Art T Grockalockfickafockamei<\/code><\/pre>\n<p>If the user types a fewer than three words, then the program continues to wait until all three <em>scanf()<\/em> functions are fed. That&#8217;s not good program design, of course, which is why I instead prefer a single string-swallowing function like <em>fgets()<\/em>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The <em>scanf()<\/em> function can&#8217;t read strings with whitespace in them, so here&#8217;s a clever trick. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=2183\">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-2183","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\/2183","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=2183"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2183\/revisions"}],"predecessor-version":[{"id":2190,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2183\/revisions\/2190"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}