{"id":7493,"date":"2026-04-08T00:01:45","date_gmt":"2026-04-08T07:01:45","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7493"},"modified":"2026-04-04T14:00:52","modified_gmt":"2026-04-04T21:00:52","slug":"a-little-bit-off-the-sides-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7493","title":{"rendered":"A Little Bit Off the Sides &#8211; Solution"},"content":{"rendered":"<p>The C language woefully lacks a <em>trim()<\/em> or similar string manipulation function. Rather than let it flail in absent envy, your task for <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7479\">this month&#8217;s Exercise<\/a> is to code such a function. The goal is to remove whitespace characters from either end of a string.<br \/>\n<!--more--><br \/>\nI can think of a number of ways to craft a <em>trim()<\/em> function. My approach is to pass the string to the function, then return a modified string, leaving the original string untouched. This modified string is allocated in the function, so the new string&#8217;s address is returned. Here&#8217;s the prototype:<\/p>\n<p><code>char *trim(const char *s)<\/code><\/p>\n<p>This function calls two other functions that do the trimming: <em>rtrim()<\/em> and <em>ltrim()<\/em>, which remove whitespace from the right and left sides of a string, respectively. I favor this approach as it not only allows me to piece out the solution, but the two functions are available separately as left-right string trimming functions. Again, such functions are readily found in other programming languages.<\/p>\n<p>Aside from calling <em>rtrim()<\/em> and <em>ltrim()<\/em>, the <em>trim()<\/em> function confirms that the string passed isn&#8217;t NULL. It compares the results from <em>rtrim()<\/em> and <em>ltrim()<\/em> to ensure that an empty string doesn&#8217;t result, which must be specially handled. Otherwise, storage is allocated for the new string and characters copied into it.<\/p>\n<p>I also made a few modifications to the <em>main()<\/em> function: A test is made for the NULL return from the <em>trim()<\/em> function. Upon success, the pointer returned is freed. (If not, the allocated memory goes untracked.)<\/p>\n<p>Here is my solution:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_04-Exercise.c\" rel=\"noopener\" target=\"_blank\">2026_04-Exercise.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;ctype.h&gt;\r\n\r\n<span class=\"comments\">\/* find the first non-space character\r\n   on the right *\/<\/span>\r\nchar *rtrim(char *s)\r\n{\r\n    char *right = NULL;\r\n\r\n    right = s+strlen(s)-1;\r\n    while( isspace(*right) )\r\n    {\r\n        right--;\r\n    }\r\n\r\n    return(right);\r\n}\r\n\r\n<span class=\"comments\">\/* find the first non-space character\r\n   on the left *\/<\/span>\r\nchar *ltrim(char *s)\r\n{\r\n    char *left = NULL;\r\n\r\n    left = s;\r\n    while( isspace(*left) )\r\n    {\r\n        if( *left=='\\0' )\r\n            break;\r\n        left++;\r\n    }\r\n\r\n    return(left);\r\n}\r\n\r\n<span class=\"comments\">\/* trim spaces from the left and right\r\n   of a string; return the new string *\/<\/span>\r\nchar *trim(char *s)\r\n{\r\n    char *trimmed,*front,*back;\r\n    int offset;\r\n\r\n    <span class=\"comments\">\/* test for NULL pointer *\/<\/span>\r\n    if( s==NULL )\r\n        return(s);    <span class=\"comments\">\/* return NULL pointer *\/<\/span>\r\n\r\n    <span class=\"comments\">\/* find the ends *\/<\/span>\r\n    back = rtrim(s);\r\n    front = ltrim(s);\r\n\r\n    <span class=\"comments\">\/* allocate storage *\/<\/span>\r\n    if( back&gt;front )\r\n        <span class=\"comments\">\/* string contains some text *\/<\/span>\r\n        trimmed = malloc( sizeof(char) * (back-front) + 1 );\r\n    else\r\n        <span class=\"comments\">\/* string is empty or all spaces *\/<\/span>\r\n        trimmed = malloc( sizeof(char) * 1 );\r\n\r\n    <span class=\"comments\">\/* create the trimmed string *\/<\/span>\r\n    if( trimmed!=NULL )\r\n    {\r\n        <span class=\"comments\">\/* empty string test *\/<\/span>\r\n        if( sizeof(trimmed)==1 )\r\n        {\r\n            *trimmed = '\\0';        <span class=\"comments\">\/* empty string *\/<\/span>\r\n        }\r\n        else\r\n        {\r\n            <span class=\"comments\">\/* copy the center *\/<\/span>\r\n            offset = 0;\r\n            while( front&lt;=back )\r\n            {\r\n                *(trimmed+offset) = *front;\r\n                front++;\r\n                offset++;\r\n            }\r\n            *(trimmed+offset)='\\0';\r\n        }\r\n    }\r\n\r\n    return(trimmed);\r\n}\r\n\r\nint main()\r\n{\r\n    char *sample[] = {\r\n        \"   one   \",\r\n        \"\\ttwo\\n\",\r\n        \"\",\r\n        \"    \",\r\n        \"a\",\r\n        \" x \",\r\n        NULL,\r\n        \" \\t three \\n\",\r\n        \"four\",\r\n        \"  five\",\r\n        \"six    \",\r\n        \" seven eight \"\r\n    };\r\n    int size,x;\r\n    char *t;\r\n\r\n    <span class=\"comments\">\/* obtain array size *\/<\/span>\r\n    size = sizeof(sample)\/sizeof(sample[0]);\r\n\r\n    <span class=\"comments\">\/* output trimmed strings *\/<\/span>\r\n    for( x=0; x&lt;size; x++ )\r\n    {\r\n        printf(\"'%s' =&gt; \",sample[x]);\r\n        t = trim(sample[x]);\r\n        if( t==NULL )\r\n        {\r\n            printf(\"Bad string\\n\");\r\n        }\r\n        else\r\n        {\r\n            printf(\"'%s'\\n\",t);\r\n            free(t);\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Both the <em>rtrim()<\/em> and <em>ltrim()<\/em> functions use the <em>isspace()<\/em> function to check for spaces, prototyped in the <code>chtype.h<\/code> header file. This function is used in a <em>while<\/em> loop to locate spaces at the start and end of the string. Both functions return a pointer to the first non-space character, right and left, in the string.<\/p>\n<p>In the <em>trim()<\/em> function, an initial test is made to determine whether a NULL pointer was passed. If so, the same pointer is returned. For all other strings, the <em>rtrim()<\/em> and <em>ltrim()<\/em> functions are called. Each function returns a pointer holding the address of the first non-space characters in the string, <code>back<\/code> and <code>front<\/code>.<\/p>\n<p>A test is made to check whether the <code>back<\/code> pointer is greater than the <code>front<\/code> pointer. If so, the string contains some text. Storage is allocated for the text, plus one for the null character.<\/p>\n<p>When the <code>back<\/code> pointer is less than or equal to the <code>front<\/code> pointer, the string is either empty or contains all whitespace characters. If so, storage is allocated for only a single character, which creates an <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=2641\">empty string<\/a>.<\/p>\n<p>The next part of the function fills the <code>trimmed<\/code> string with characters. If the size of <code>trimmed<\/code> is one byte, the null character is set. Otherwise, characters are copied from the passed string (<code>s<\/code>) to the allocated string (<code>trimmed<\/code>). The string is capped with a null character and returned.<\/p>\n<p>Here&#8217;s a sample run of my solution:<\/p>\n<pre>'   one   ' => 'one'\r\n'       two\r\n' => 'two'\r\n'' => ''\r\n'    ' => ''\r\n'a' => 'a'\r\n' x ' => 'x'\r\n'(null)' => Bad string\r\n'        three\r\n' => 'three'\r\n'four' => 'four'\r\n'  five' => 'five'\r\n'six    ' => 'six'<\/pre>\n<p>This exercise proved more difficult than I originally thought. In fact, my first solution didn&#8217;t consider the final sample string where spaces are found in the middle. My second solution didn&#8217;t account for empty strings or strings composed entirely of spaces. The key for me was first coding the <em>rtrim()<\/em> and <em>ltrim()<\/em> functions, which made the rest of the process easier.<\/p>\n<p>I hope that your solution met with success.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The C language woefully lacks a trim() or similar string manipulation function. Rather than let it flail in absent envy, your task for this month&#8217;s Exercise is to code such a function. The goal is to remove whitespace characters from &hellip; <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7493\">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":[5],"tags":[],"class_list":["post-7493","post","type-post","status-publish","format-standard","hentry","category-solution"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7493","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=7493"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7493\/revisions"}],"predecessor-version":[{"id":7527,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7493\/revisions\/7527"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}