{"id":3908,"date":"2019-12-28T00:01:36","date_gmt":"2019-12-28T08:01:36","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3908"},"modified":"2019-12-21T10:29:43","modified_gmt":"2019-12-21T18:29:43","slug":"my-own-strlcat-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3908","title":{"rendered":"My own <em>strlcat()<\/em> Function"},"content":{"rendered":"<p>Coding my own version of the non-standard <em>strlcat()<\/em> function proved to be a bit more work than I anticipated. That&#8217;s because I also had to code my own versions of the <em>strcpy()<\/em> and <em>strlen()<\/em> functions to make the thing work.<br \/>\n<!--more--><br \/>\nThe reason I couldn&#8217;t use the standard library versions of <em>strcpy()<\/em> and <em>strlen()<\/em> is that the <code>string.h<\/code> header also brings in the definition of <em>strlcat()<\/em>; the two prototypes would conflict. Further, I chose to code my own version of <em>strcpy() <\/em>as opposed to using the <em>strlcpy()<\/em> code <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3886\">from a Lesson<\/a> I wrote a few weeks back.<\/p>\n<blockquote><p>If <em>strlcat()<\/em> isn&#8217;t available in the library, you need not code your own <em>strcpy()<\/em> and <em>strlen()<\/em> functions as there would be no conflict in the <code>string.h<\/code> header.<\/p><\/blockquote>\n<p>Thanks to the research done from <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3896\">last week&#8217;s Lesson<\/a>, I know the return value of the <em>strlcat()<\/em> function: the combined length of both the source and destination strings:<\/p>\n<p><code>d_len = strlen(dst);<br \/>\ns_len = strlen(src);<\/code><\/p>\n<p>Further, the <code>d_len<\/code> value is used to find the offset in the <code>dst<\/code> buffer where the string is appended. Here is my version of the <em>strlcat()<\/em> function:<\/p>\n<pre class=\"screen\">\r\nsize_t strlcat(char *restrict dst, const char *restrict src, size_t dstsize)\r\n{\r\n    int d_len,s_len,offset,src_index;\r\n\r\n    <span class=\"comments\">\/* obtain initial sizes *\/<\/span>\r\n    d_len = strlen(dst);\r\n    s_len = strlen(src);\r\n\r\n    <span class=\"comments\">\/* get the end of dst *\/<\/span>\r\n    offset = d_len;\r\n\r\n    <span class=\"comments\">\/* append src *\/<\/span>\r\n    src_index = 0;\r\n    while( *(src+src_index) != '\\0' )\r\n    {\r\n        *(dst+offset) = *(src+src_index);\r\n        offset++;\r\n        src_index++;\r\n        <span class=\"comments\">\/* don't copy more than dstsize characters\r\n           minus one *\/<\/span>\r\n        if( offset==dstsize-1)\r\n            break;\r\n    }\r\n    <span class=\"comments\">\/* always cap the string! *\/<\/span>\r\n    *(dst+offset) = '\\0';\r\n\r\n    return( d_len+s_len );\r\n}<\/pre>\n<p>The function&#8217;s <em>while<\/em> loop copies characters from <code>src<\/code> to <code>dst<\/code> until the end of string <code>src<\/code>:<\/p>\n<p><code>*(dst+offset) = *(src+src_index);<\/code><\/p>\n<p>Variables <code>offset<\/code> and <code>src_index<\/code> track the positions within each buffer, with <code>offset<\/code> compared against argument <code>dstsize<\/code> to check for overflows:<\/p>\n<p><code>if( offset==dstsize-1)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;break;<\/code><\/p>\n<p>The code&#8217;s <em>main()<\/em> function is the same as presented last week. To view the full code, including my versions of <em>strcpy()<\/em> and <em>strlen()<\/em>, <a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2019_12_28-Lesson.c\" rel=\"noopener noreferrer\" target=\"_blank\">click here<\/a> (GitHub).<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>This is a poten<br \/>\nValue returned: 33<br \/>\nString truncated<\/code><\/p>\n<p>The output is identical to the test code presented in last week&#8217;s Lesson. When the buffer size is changed to 64, the result is also identical:<\/p>\n<p><code>This is a potentially long string<br \/>\nValue returned: 33<br \/>\nString was fully copied<\/code><\/p>\n<p>I thought this reverse engineering task would be more difficult than the job I did for <em>strlcpy()<\/em>, but I was wrong. (Well, save for also re-writing the <em>strcpy()<\/em> and <em>strlen()<\/em> functions.) The key to emulating a library function is to run multiple tests on the original. Try to discern what the function is doing internally. The goal is to mimic that behavior so that you can use the function on a C compiler that&#8217;s standard, or one that lacks the function you&#8217;re trying to emulate.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Writing my own <em>strlcat()<\/em> function proved easier once I figured out how the non-standard library function behaved. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3908\">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-3908","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\/3908","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=3908"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3908\/revisions"}],"predecessor-version":[{"id":3915,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3908\/revisions\/3915"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}