{"id":5980,"date":"2023-08-08T00:01:04","date_gmt":"2023-08-08T07:01:04","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5980"},"modified":"2023-08-12T08:38:55","modified_gmt":"2023-08-12T15:38:55","slug":"from-camelcase-to-snake_case-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5980","title":{"rendered":"From camelCase to snake_case &#8211; Solution"},"content":{"rendered":"<p>The challenge for <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5967\">this month&#8217;s Exercise<\/a> is to convert a name from camelCase to snake_case and vice-versa. As usual, several approaches provide a possible solution. The directions were to output the results and not store them, so my solution is rather simple.<br \/>\n<!--more--><br \/>\nThe first part of any solution is to identify the naming convention. Because snake_case uses the underscore, I use the <em>strchr()<\/em> function to scan for this character to determine whether it&#8217;s snake_case. If the character isn&#8217;t found, I can assume that camelCase is used instead. I recognize more assertive methods of determining the naming convention are possibly better, though for this Exercise the list of names provided is formatted consistently.<\/p>\n<p>The <em>strchr()<\/em> function scans a named string for a specific character. If found, a pointer to the character&#8217;s offset is returned. Otherwise, NULL is returned:<\/p>\n<p><code>if( strchr(variable[x],'_') )<\/code><\/p>\n<p>The above statement is TRUE when the underscore is found in string <code>variable[x]<\/code>. This statement is the key to my solution, which uses an <em>if-else<\/em> structure within a <em>for<\/em> loop to process the sample names provided.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2023_08-Exercise.c\" rel=\"noopener\" target=\"_blank\">2023_08-Exercise.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;ctype.h&gt;\r\n\r\nint main()\r\n{\r\n    const int count = 7;\r\n    char *variable[] = {\r\n        \"readInputMeter\",\r\n        \"cyclical_redundancy_check\",\r\n        \"bumpyRide\",\r\n        \"search_for_node\",\r\n        \"string_convert\",\r\n        \"divideByZeroError\",\r\n        \"giveUpAndExplode\"\r\n    };\r\n    int x;\r\n    char *n;\r\n\r\n    for(x=0; x&lt;count; x++ )\r\n    {\r\n        printf(\"%25s -&gt; \",variable[x]);\r\n        n = variable[x];        <span class=\"comments\">\/* initialize pointer n *\/<\/span>\r\n\r\n        <span class=\"comments\">\/* test for the underscore *\/<\/span>\r\n        if( strchr(variable[x],'_') )\r\n        {\r\n            <span class=\"comments\">\/* name is in snake_case *\/<\/span>\r\n            while( *n )\r\n            {\r\n                if( *n=='_' )\r\n                {\r\n                    n++;\r\n                    <span class=\"comments\">\/* test for overflow *\/<\/span>\r\n                    if( *n=='\\0' ) break;\r\n                    putchar( toupper(*n) );\r\n                }\r\n                else\r\n                {\r\n                    putchar(*n);\r\n                }\r\n                n++;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            <span class=\"comments\">\/* name is in camelCase *\/<\/span>\r\n            while( *n )\r\n            {\r\n                if( isupper(*n) )\r\n                {\r\n                    putchar('_');\r\n                    putchar( tolower(*n) );\r\n                }\r\n                else\r\n                {\r\n                    putchar(*n);\r\n                }\r\n                n++;\r\n            }\r\n        }\r\n        putchar('\\n');\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Pointer <code>n<\/code> scours each character in string <code>variable[x]<\/code>. For snake_case, <code>*n<\/code> is compared with the underscore: <code>if( *n=='_' )<\/code> When an underscore is found, pointer <code>n<\/code> is incremented (over the underscore) to the next character: <code>n++;<\/code><\/p>\n<p>A test is performed after incrementing <code>n<\/code> just in case the underscore ends the string: <code>if( *n=='\\0' ) break;<\/code> If true, the loop breaks. Otherwise, the uppercase version of the next character is output: <code>putchar( toupper(*n) );<\/code><\/p>\n<p>All other characters are handled in the <em>else<\/em> part of the decision, output directly: <code>putchar(*n);<\/code><\/p>\n<p>Pointer <code>n<\/code> is incremented after the nested <em>if-else<\/em> structure, continuing to churn through string <code>variable[x]<\/code>.<\/p>\n<p>Strings that aren&#8217;t identified as snake_case are camelCase. To process these strings, a <em>while<\/em> loop contains a nested <em>if-else<\/em> structure. The test here is whether a letter is in uppercase: <code>if( isupper(*n) )<\/code><\/p>\n<p>When found, an underscore is output, <code>putchar('_');<\/code>, then the current character is output in lowercase: <code>putchar( tolower(*n) );<\/code> Otherwise, the character is output unmodified and <code>n<\/code> is incremented after the nested <em>if-else<\/em> construction.<\/p>\n<p>The new strings are output immediately, which ends the string originally generated by a <em>printf()<\/em> statement:<\/p>\n<p><code>printf(\"%25s -&gt; \",variable[x]);<\/code><\/p>\n<p>The <code>%25s<\/code> placeholder right-justifies the string, which makes the output appear symmetrical:<\/p>\n<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readInputMeter&nbsp;-&gt;&nbsp;read_input_meter<br \/>\ncyclical_redundancy_check&nbsp;-&gt;&nbsp;cyclicalRedundancyCheck<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bumpyRide&nbsp;-&gt;&nbsp;bumpy_ride<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;search_for_node&nbsp;-&gt;&nbsp;searchForNode<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string_convert&nbsp;-&gt;&nbsp;stringConvert<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;divideByZeroError&nbsp;-&gt;&nbsp;divide_by_zero_error<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;giveUpAndExplode&nbsp;-&gt;&nbsp;give_up_and_explode<\/code><\/p>\n<p>I hope your solution met with success. You get a special <em>C For Dummies<\/em> bonus point if you stored the strings before output. In fact, I cover this approach in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5988\">an upcoming Lesson<\/a>. Storing the strings adds more overhead, but it still works &mdash; and is probably a better solution as opposed to immediate output.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The challenge for this month&#8217;s Exercise is to convert a name from camelCase to snake_case and vice-versa. As usual, several approaches provide a possible solution. The directions were to output the results and not store them, so my solution is &hellip; <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5980\">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-5980","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\/5980","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=5980"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5980\/revisions"}],"predecessor-version":[{"id":6002,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5980\/revisions\/6002"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5980"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5980"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}