{"id":5326,"date":"2022-04-30T00:01:23","date_gmt":"2022-04-30T07:01:23","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5326"},"modified":"2022-04-23T09:37:30","modified_gmt":"2022-04-23T16:37:30","slug":"outputting-an-unterminated-buffer","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5326","title":{"rendered":"Outputting an Unterminated Buffer"},"content":{"rendered":"<p>Properly formed strings in C are terminated with the null character, <code>\\0<\/code>. Accept it or die!<\/p>\n<p>However . . .<br \/>\n<!--more--><br \/>\nIt does happen, occasionally, that a chunk of memory is formed that holds text in an unterminated state. In this situation, you must either code a method to output the text or properly terminate the string so that it behaves like other strings.<\/p>\n<p>For example, data received in a network packet appears in a buffer unterminated. As a programmer, you&#8217;ve given the buffer&#8217;s address and the size of the data received. These values, the buffer and the data size, are another way to represent a string, though what you want is the data size to be less than the buffer size so that you can properly convert the text into a string. (When the buffer is full, no room is available to append the terminating null character.)<\/p>\n<p>The key to converting the buffer&#8217;s character data into text, or just outputting the text directly, is knowing the character count. This tidbit is provided in a network packet and what I simulate in this Lesson: An 18-byte buffer is filled with ten characters. No terminated null character is added, but the character count is known, stored in an <em>int<\/em> constant. This character count is key to converting the characters into a string.<\/p>\n<p>This first example shows how you can output the text, though it doesn&#8217;t convert the characters into a string:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_04_30-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2022_04_30-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    const int size=10;    <span class=\"comments\">\/* number of characters in the buffer *\/<\/span>\r\n    char buffer[size+8];    <span class=\"comments\">\/* larger buffer size *\/<\/span>\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* fill the buffer - not a string *\/<\/span>\r\n    for( x=0; x&lt;size; x++ )\r\n        buffer[x] = 'A'+x;\r\n\r\n    <span class=\"comments\">\/* output the buffer *\/<\/span>\r\n\r\n    for( x=0; x&lt;size; x++ )    <span class=\"comments\">\/* one character at a time *\/<\/span>\r\n        putchar(buffer[x]);\r\n    putchar('\\n');            <span class=\"comments\">\/* convenient newline *\/<\/span>\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>putchar()<\/em> function at Line 16 pops out one character at time. You could also perform the same feat by using a single <em>printf()<\/em> function:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_04_30-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2022_04_30-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    const int size=10;    <span class=\"comments\">\/* number of characters in the buffer *\/<\/span>\r\n    char buffer[size+8];    <span class=\"comments\">\/* larger buffer size *\/<\/span>\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* fill the buffer - not a string *\/<\/span>\r\n    for( x=0; x&lt;size; x++ )\r\n        buffer[x] = 'A'+x;\r\n\r\n    <span class=\"comments\">\/* output the buffer *\/<\/span>\r\n\r\n    printf(\"%.*s\\n\",size,buffer);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>printf()<\/em> format string uses the <code>*<\/code> <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=2972\">variable width placeholder<\/a> to set the string&#8217;s output width, using the <code>size<\/code> variable in the argument list. The characters are output, but they remain in the buffer without being converted into a string.<\/p>\n<p>This final trick converts the text into a true string, thanks to the code knowing the number of characters in the buffer.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_04_30-Lesson-c.c\" rel=\"noopener\" target=\"_blank\">2022_04_30-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    const int size=10;    <span class=\"comments\">\/* number of characters in the buffer *\/<\/span>\r\n    char buffer[size+8];    <span class=\"comments\">\/* larger buffer size *\/<\/span>\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* fill the buffer - not a string *\/<\/span>\r\n    for( x=0; x&lt;size; x++ )\r\n        buffer[x] = 'A'+x;\r\n\r\n    <span class=\"comments\">\/* output the buffer *\/<\/span>\r\n\r\n    buffer[size] = '\\0';    <span class=\"comments\">\/* cap the string *\/<\/span>\r\n    puts(buffer);            <span class=\"comments\">\/* output the string *\/<\/span>\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The assignment at Line 15 caps the string. Offset <code>size<\/code> sets the null character&#8217;s position in the buffer. A string is created, which is then dealt with like any string. Here is the output &mdash; identical for each code sample in this Lesson:<\/p>\n<p><code>ABCDEFGHIJ<\/code><\/p>\n<p>The only problem with the last example is that it&#8217;s possible to overflow the buffer when the number of characters in the buffer matches the buffer size. This reason is why many coders prefer the preceding two techniques to just output the text over capping the text and creating a string within the buffer. The choice is up to you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>All string buffers must be terminated with a null character, unless they aren&#8217;t. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5326\">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-5326","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\/5326","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=5326"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5326\/revisions"}],"predecessor-version":[{"id":5339,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5326\/revisions\/5339"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5326"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5326"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5326"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}