{"id":3200,"date":"2018-07-28T00:01:58","date_gmt":"2018-07-28T07:01:58","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3200"},"modified":"2018-07-21T09:46:23","modified_gmt":"2018-07-21T16:46:23","slug":"to-split-a-string-in-c","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3200","title":{"rendered":"To Split a String in C"},"content":{"rendered":"<p>Have you ever heard a programmer mock the C language? Recently, a C# programmer informed me that C was okay, but &#8220;you can&#8217;t even split a string in C in less than 20 lines of code.&#8221;<\/p>\n<p>Challenge accepted!<br \/>\n<!--more--><br \/>\nThe C# language has several fun and interesting string methods, which are like functions for object-oriented languages. You can parse strings, replace text within a string, and a whole host of fun and useful tasks. But C was specifically mocked regarding its inability to split a string by using a tidy number of statements.<\/p>\n<p>I&#8217;m not going to bother to research how C# splits a string. Instead, I concocted a function with four arguments:<\/p>\n<p><code>int split(char *original, int offset, char **s1, char **s2)<\/code><\/p>\n<p><em>original<\/em> is the original string, the one to be split in two.<\/p>\n<p><em>offset<\/em> is the character position at which the string is to be split, with <em>offset<\/em> characters sent to the first string and the remaining characters sent to the second.<\/p>\n<p><em>s1<\/em> and <em>s2<\/em> are pointer-pointers representing the strings to contain the split. They&#8217;re declared in the calling function as pointer variables with their addresses are passed to the function, which is why I use the <code>**<\/code> notation. More on this process in a few paragraphs.<\/p>\n<p>The <em>split()<\/em> function returns 1 upon success, 0 otherwise.<\/p>\n<p>The good news is that the function, which I wrote in my standard way of formatting the C language (no collapsed statements or anything tricky) is only 15 lines long.<\/p>\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\r\nint split(char *original,int offset,char **s1,char **s2)\r\n{\r\n    int len;\r\n\r\n    len = strlen(original);\r\n    if(offset &gt; len)\r\n        return(0);\r\n    *s1 = (char *)malloc(sizeof(char) * offset+1);\r\n    *s2 = (char *)malloc(sizeof(char) * len-offset+1);\r\n    if( s1==NULL || s2==NULL )\r\n        return(0);\r\n    strncpy(*s1,original,offset);\r\n    strncpy(*s2,original+offset,len-offset);\r\n    return(1);\r\n}\r\n\r\nint main()\r\n{\r\n    char string[] = \"We shall attempt to split this string\";\r\n    char *first,*second;\r\n    int r;\r\n\r\n    r = split(string,16,&amp;first,&amp;second);\r\n    if(r==1)\r\n    {\r\n        printf(\"Split successful\\n\");\r\n        printf(\"'%s' split into:\\n\",string);\r\n        printf(\"'%s'\\n\",first);\r\n        printf(\"'%s'\\n\",second);\r\n    }\r\n    else\r\n    {\r\n        puts(\"The function was unable to split the string\");\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The first thing the <em>split()<\/em> function does is to obtain the length of the original string:<\/p>\n<p><code>len = strlen(original);<br \/>\nif(offset &gt; len)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;return(0);<\/code><\/p>\n<p>If the split (<code>offset<\/code>) is greater than the string&#8217;s length, the function returns 0, failure. (The function can &#8220;split&#8221; a string the same length as the original string, in which case you end up with a copy of the original string and an empty string.)<\/p>\n<p>Second, storage is allocated for the two string buffers. These variables are passed as addresses because you cannot modify a pointer variable argument directly within a function; you must pass the address of the pointer variable instead. (Check Line 27 in the <em>main()<\/em> function.)<\/p>\n<p><code>*s1 = (char *)malloc(sizeof(char) * offset+1);<br \/>\n*s2 = (char *)malloc(sizeof(char) * len-offset+1);<br \/>\nif( s1==NULL || s2==NULL )<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;return(0);<\/code><\/p>\n<p>Storage is allocated for the size of each new string, <code>+1<\/code> for the null character, <code>\\0<\/code>. If either allocation fails, the function returns with 0, failure.<\/p>\n<p>Finally, given the size of the original string and the split, two <em>strncpy()<\/em> functions copy portions of the original string into the two, freshly-allocated string buffers:<\/p>\n<p><code>strncpy(*s1,original,offset);<br \/>\nstrncpy(*s2,original+offset,len-offset);<\/code><\/p>\n<p>The first <em>strncpy()<\/em> function copies characters into the first string, <code>s1<\/code>, up to and including the split at <code>offset<\/code>. The second <em>strncpy()<\/em> function starts at <code>offset<\/code> and copies the rest of the characters into string <code>s2<\/code>.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<pre><code>Split successful\r\n'We shall attempt to split this string' split into:\r\n'We shall attempt'\r\n' to split this string'<\/code><\/pre>\n<p>If you can concoct a solution shorter than 15 lines, and without cramming all the statements on a single line, I&#8217;d enjoy seeing it. I&#8217;d love to show Mr. Smartypants C# Programmer that C is more than up to the task of splitting a string in fewer than 20 lines.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yes, those hauteur programming languages have some simple tricks, but nothing that C is incapable of doing. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3200\">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-3200","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\/3200","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=3200"}],"version-history":[{"count":7,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3200\/revisions"}],"predecessor-version":[{"id":3214,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3200\/revisions\/3214"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3200"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3200"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3200"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}