{"id":5445,"date":"2022-07-16T00:01:02","date_gmt":"2022-07-16T07:01:02","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5445"},"modified":"2022-07-09T09:21:01","modified_gmt":"2022-07-09T16:21:01","slug":"having-fun-with-the-getline-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5445","title":{"rendered":"Having Fun with the <em>getline()<\/em> Function"},"content":{"rendered":"<p>In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5432\">last week&#8217;s post<\/a>, I updated information I had originally written about the useful <em>getline()<\/em> function. The topic is worthy of further exploration, specifically with the mechanics behind the function&#8217;s internal allocation &mdash; and reallocation &mdash; of memory.<br \/>\n<!--more--><br \/>\nThe <em>getline()<\/em> function allocates memory when passed a <em>char<\/em> pointer initialized to <code>NULL<\/code>. If more storage is required, the function automatically re-allocates the pointer. To demonstrate how this internal operation behaves, I concocted the following code.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_07_16-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2022_07_16-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nint main()\r\n{\r\n    char *buffer = NULL;\r\n    size_t size;\r\n    int r;\r\n\r\n    <span class=\"comments\">\/* repeat until a blank line is input *\/<\/span>\r\n    do\r\n    {\r\n        <span class=\"comments\">\/* prompt and gather input *\/<\/span>\r\n        printf(\"Type: \");\r\n        r = getline( &amp;buffer, &amp;size, stdin );\r\n\r\n        <span class=\"comments\">\/* show input *\/<\/span>\r\n        printf(\"You typed (%d): %s\",r,buffer);\r\n\r\n    } while( r&gt;1 );\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The above code doesn&#8217;t even bother to initialize variable <code>size<\/code>; it doesn&#8217;t matter! The <em>getline()<\/em> function allocates as much storage as needed.<\/p>\n<p>At Line 15, the function returns the number characters input, including the newline. The value -1 is returned upon error and zero for an empty string (which can&#8217;t be input directly from the keyboard). The <em>do-while<\/em> loop repeats until a blank line is input (<code>r<\/code> is one or less). Here&#8217;s a sample run:<\/p>\n<p><code>Type: This is some text<br \/>\nYou typed (18): This is some text<br \/>\nType: Even more text<br \/>\nYou typed (15): Even more text<br \/>\nType:<br \/>\nYou typed (1):<\/code><\/p>\n<p>This code demonstrates that the function can be called again and again, each time processing the text input regardless of the extant values of <code>buffer<\/code> and <code>size<\/code>. I wondered whether the buffer is allocated afresh for every call, in which case it could be saved. This way <em>getline()<\/em> can process several lines of text while reusing the same variables. So I wrote this code:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_07_16-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2022_07_16-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nint main()\r\n{\r\n    const int range = 5;\r\n    char *buffer = NULL;\r\n    char *text[range];\r\n    size_t size;\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* gather `range` lines of input *\/<\/span>\r\n    for( x=0; x&lt;range; x++ )\r\n    {\r\n        printf(\"Line #%d\/%d: \",x+1,range);        <span class=\"comments\">\/* add one for humans *\/<\/span>\r\n        getline( &amp;buffer, &amp;size, stdin );\r\n        text[x] = buffer;\r\n    }\r\n\r\n    <span class=\"comments\">\/* output the text *\/<\/span>\r\n    for( x=0; x&lt;range; x++ )\r\n    {\r\n        printf(\"%s\",text[x]);\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>In this update to the code, the first <em>for<\/em> loop uses <em>getline()<\/em> to fetch five lines of text. The buffer for each allocated line is saved in the <code>text[]<\/code> <em>char<\/em> pointer array. The second loop outputs each of the stored lines. But it doesn&#8217;t really work:<\/p>\n<p><code>Line #1\/5: Line one<br \/>\nLine #2\/5: This is line two<br \/>\nLine #3\/5: Line three<br \/>\nLine #4\/5: Almost done<br \/>\nLine #5\/5: Last line!<br \/>\nLine one<br \/>\nLast line!<br \/>\nLast line!<br \/>\nLast line!<br \/>\nLast line!<\/code><\/p>\n<p>Because the second line is longer than the first, <code>buffer<\/code> is reallocated by <em>getline()<\/em>. As the remaining lines are shorter, <code>buffer<\/code> isn&#8217;t reallocated. Even then, copying the address of <code>buffer<\/code> into <code>text[x]<\/code> (at Line 17) is a poor way to retain the text input. It relies upon the assumption that each call to <em>getline()<\/em> allocates another buffer, which demonstrably isn&#8217;t the case.<\/p>\n<p>The moral of the story is that you can use <em>getline()<\/em> to capture a single line of text, use the text in some manner, then use <em>getline()<\/em> again with the same arguments. Never assume that a new buffer is created for each call. Further, to save the text you must allocate a new buffer and copy the text into it.<\/p>\n<p>Oh, and you can free the buffer after you&#8217;ve used it. I don&#8217;t in my examples because <em>getline()<\/em> appears only in the <em>main()<\/em> function, where memory is freed when the program terminates.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To enjoy the <em>getline()<\/em> function you must understand its internal workings. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5445\">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-5445","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\/5445","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=5445"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5445\/revisions"}],"predecessor-version":[{"id":5453,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5445\/revisions\/5453"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}