{"id":6735,"date":"2025-01-04T00:01:18","date_gmt":"2025-01-04T08:01:18","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6735"},"modified":"2025-01-04T18:56:36","modified_gmt":"2025-01-05T02:56:36","slug":"building-a-string","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6735","title":{"rendered":"Building a String"},"content":{"rendered":"<p>Programming language more modern than C sport great libraries of functions, or &#8220;methods.&#8221; Java has so many I doubt that a single programmer knows them all. In C, however, when a function is absent (and a lot of them are, comparably), you must code your own. Such is the case with building a string.<br \/>\n<!--more--><br \/>\nThe C language features the <em>strcat()<\/em> function, which sticks one string onto the end of another. To continue building the string, you use additional <em>strcat()<\/em> functions, sometimes several in a row. When this situation happened to me recently, I decided to craft my own string building function, something that&#8217;s readily available in other programming languages.<\/p>\n<p>The function I created is called <em>concatenate()<\/em>. It consumes a number of strings, sticks them all together, then returns a single string. Because the number of strings is variable, I use a variable argument list in the function&#8217;s definition:<\/p>\n<p><code>char *concatenate(int v, ...)<\/code><\/p>\n<p>Integer <code>v<\/code> represents the number of arguments, which appear as <code>...<\/code> in the declaration. You can read more about variable argument lists in this <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3398\">blog post<\/a>.<\/p>\n<p>Here is sample code that demonstrates my <em>concatenate()<\/em> function:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2025_01_04-Lesson.c\" rel=\"noopener\" target=\"_blank\">2025_01_04-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;stdarg.h&gt;\r\n\r\nchar *concatenate(int v, ...)\r\n{\r\n    va_list argc;\r\n    int x;\r\n    char *r,*temp;\r\n\r\n    va_start(argc,v);\r\n    for(x=0; x&lt;v; x++)\r\n    {\r\n        temp = va_arg(argc,char *);\r\n        if( x==0 )\r\n        {\r\n            r = malloc( sizeof(char) * strlen(temp) +1 );\r\n            if( r==NULL )\r\n                return(\"NULL\");\r\n            strcpy(r,temp);\r\n        }\r\n        else\r\n        {\r\n            r = realloc(r, sizeof(char) * (strlen(r) + strlen(temp)) +1 );\r\n            if( r==NULL )\r\n                return(\"NULL\");\r\n            strcat(r,temp);\r\n        }\r\n    }\r\n\r\n    <span class=\"comments\">\/* clean up *\/<\/span>\r\n    va_end(argc);\r\n    return(r);\r\n}\r\n\r\nint main()\r\n{\r\n    char *a,*b,*c;\r\n\r\n    a = concatenate(4,\"alpha \",\"beta \",\"gamma \",\"delta\");\r\n    printf(\"%s\\n\",a);\r\n\r\n    b = concatenate(1,\"Hello, world!\");\r\n    printf(\"%s\\n\",b);\r\n\r\n    c = concatenate(6,\"f\",\"o\",\"o\",\"b\",\"a\",\"r\");\r\n    printf(\"%s\\n\",c);\r\n\r\n    <span class=\"comments\">\/* clean-up *\/<\/span>\r\n    free(a);\r\n    free(b);\r\n    free(c);\r\n    return 0;\r\n}<\/pre>\n<p>The <code>stdarg.h<\/code> header is required to manipulate the variable argument list and define the <em>va_start()<\/em>, <em>va_arg()<\/em> and <em>va_end()<\/em> macros.<\/p>\n<p>The <em>main()<\/em> function calls the <em>concatenate()<\/em> function three times. Each statement uses differently formatted strings and a different number of arguments. The function staples strings together as-is; no spaces are inserted between them.<\/p>\n<p>The <em>concatenate()<\/em> function obtains the argument count from the <em>va_start()<\/em> macro. This value, saved in variable <code>v<\/code>, is used in a <em>for<\/em> loop to process each of the arguments. The <em>char<\/em> pointer variable <code>temp<\/code> references each string: <code>temp = va_arg(argc,char *);<\/code><\/p>\n<p>An <em>if<\/em> decision determines when the first string is added. If so, the <em>malloc()<\/em> function allocates storage for the string, then copies it into the allocated buffer, <code>r<\/code>. Otherwise, the <em>else<\/em> condition uses the <em>realloc()<\/em> function to reallocate storage for the next string plus the existing string. The <em>strcat()<\/em> function sticks the string to the end of the string being built and referenced by <em>char<\/em> pointer variable <code>r<\/code>.<\/p>\n<p>After the string is built, the <em>va_end()<\/em> function cleans up the variable argument list. Variable <code>r<\/code>, referencing the built string, is returned to the caller.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>alpha beta gamma delta<br \/>\nHello, world!<br \/>\nfoobar<\/code><\/p>\n<p>This code works, thanks to variable argument lists. The value returned is a pointer, so it need not be made <em>static<\/em>. In my program, separate pointers store the returned strings&#8217; addresses, which are freed before the program quits.<\/p>\n<p>I&#8217;m quite pleased with my <em>concatenate()<\/em> function and welcome its addition to my personal string library. I hope you also appreciate that C lets you create such functions when needed. While programmers in other languages may be annoyed at this type of task, I think it&#8217;s one of the better aspects of C programming.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When the C language lacks a function to do what you want, you build your own. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6735\">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-6735","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\/6735","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=6735"}],"version-history":[{"count":7,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6735\/revisions"}],"predecessor-version":[{"id":6809,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6735\/revisions\/6809"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}