{"id":5974,"date":"2023-08-05T00:01:51","date_gmt":"2023-08-05T07:01:51","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5974"},"modified":"2023-07-29T12:00:34","modified_gmt":"2023-07-29T19:00:34","slug":"using-scanf-to-build-a-string-part-v","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5974","title":{"rendered":"Using <em>scanf()<\/em> to Build a String &#8211; Part V"},"content":{"rendered":"<p>In my code update for <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5963\">last week&#8217;s Lesson<\/a>, I used <em>return<\/em> statements to send strings back to the <em>main()<\/em> function. This technique works &mdash; only once, even though the strings are declared <em>static<\/em> in the <em>token()<\/em> function.<br \/>\n<!--more--><br \/>\nIf you don&#8217;t classify the strings as <em>static<\/em>, the program won&#8217;t build properly. This reason is why the strings are declared on lines by themselves:<\/p>\n<p><code>static char space[] = \" \";<br \/>\nstatic char newline[] = \"\\n\";<br \/>\nstatic char tab[] = \"\\t\";<\/code><\/p>\n<p>But the sample output is ugly:<\/p>\n<p><code>Type some Text: This SP is SP a SP test NL Hello, SP world! END<br \/>\nThis isSPaSPtestHello,NLSPworld!<\/code><\/p>\n<p>I didn&#8217;t debug the program to discover why the replacement strings aren&#8217;t copied into the final string. My guess, however, is that it has something to do with their addresses. Yes, it&#8217;s a pointer issue.<\/p>\n<p>Obviously, a better solution must be found, one that allocates the strings as they&#8217;re needed. Though this may not be a simple solution, it works.<\/p>\n<p>Here is the updated <em>token()<\/em> function:<\/p>\n<pre class=\"screen\">\r\nchar *token(char *s)\r\n{\r\n    char space[] = \" \";\r\n    char newline[] = \"\\n\";\r\n    char tab[] = \"\\t\";\r\n    char *r;\r\n\r\n    <span class=\"comments\">\/* test for special strings *\/<\/span>\r\n    if( strcmp(s,\"END\")==0 )\r\n        return(NULL);\r\n    if( strcmp(s,\"SP\")==0 )\r\n    {\r\n        r = malloc( strlen(space) +1 );\r\n        strcpy(r,space);\r\n        return(r);\r\n    }\r\n    if( strcmp(s,\"NL\")==0 )\r\n    {\r\n        r = malloc( strlen(newline) +1 );\r\n        strcpy(r,newline);\r\n        return(r);\r\n    }\r\n    if( strcmp(s,\"TB\")==0 )\r\n    {\r\n        r = malloc( strlen(tab) +1 );\r\n        strcpy(r,tab);\r\n        return(r);\r\n    }\r\n\r\n    return(s);\r\n}<\/pre>\n<p>The first <em>strcmp()<\/em> comparison tests for the text END. If found, <code>NULL<\/code> is returned. No problems here.<\/p>\n<p>The next comparison is for the SP token. If found, space is allocated for a new string based on the size of string <code>space<\/code>, plus one for the null character. No testing is done here to confirm whether memory is available; if I were to release this code I would check to ensure that memory is properly allocated.<\/p>\n<p>After storage is created, the <code>space<\/code> string is copied into the new string at <code>r<\/code>. The new string&#8217;s address is returned: <code>return(r);<\/code><\/p>\n<p>This approach is used twice more with <em>if<\/em> decisions for the NL and TB tokens.<\/p>\n<p>You can <a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2023_08_05-Lesson.c\" rel=\"noopener\" target=\"_blank\">click here<\/a> to view the full code on GitHub.<\/p>\n<p>Here&#8217;s the output, using the same &#8220;aggressive&#8221; input from last week&#8217;s Lesson:<\/p>\n<p><code>Type some Text: This SP is SP a SP test NL Hello, SP world! END<br \/>\nThis is a test<br \/>\nHello, world!<\/code><\/p>\n<p>Because the strings are allocated as needed, the storage doesn&#8217;t vanish and is properly copied to the final string output.<\/p>\n<p>Yes, I&#8217;m not freeing the memory when the <em>main()<\/em> function exits. This step isn&#8217;t necessary as the program is exiting and freeing all its memory anyway. But had these routines been part of a larger program, I would definitely free the allocated memory.<\/p>\n<p>My goal with this series was to see how I could finagle the <em>scanf()<\/em> function to fetch a full string. While I&#8217;m able to use <em>scanf()<\/em> to do so, the tokens make input difficult to type and, well, ugly. Given that, and how <em>scanf()<\/em> can overflow a buffer, the best approach for string input remains using a function like <em>fgets()<\/em> instead.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Time to complete my <em>scanf()<\/em> string input function, repairing the <em>token()<\/em> function to properly return string values. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5974\">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-5974","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\/5974","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=5974"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5974\/revisions"}],"predecessor-version":[{"id":5991,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5974\/revisions\/5991"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}