{"id":4490,"date":"2020-12-08T00:01:33","date_gmt":"2020-12-08T08:01:33","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4490"},"modified":"2021-01-08T09:00:34","modified_gmt":"2021-01-08T17:00:34","slug":"some-weighty-conversions-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4490","title":{"rendered":"Some Weighty Conversions &#8211; Solution"},"content":{"rendered":"<p>This <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4482\">month&#8217;s Exercise<\/a> is to create a program that converts weight measurements by using this format:<\/p>\n<p><code><em>nnnFT<\/em><\/code><\/p>\n<p>Where <code><em>nnn<\/em><\/code> is a value, <code><em>F<\/em><\/code> is the unit to convert from, and <code><em>T<\/em><\/code> is the unit to convert to. This problem is more of an input-parsing exercise than a straight conversion.<br \/>\n<!--more--><br \/>\nFor my solution, I use an <em>if-else if-else<\/em> structure to sift through the various permutations of K (kilos), P (pounds), and S (stone). The first step, however, is to pull out the relevant information.<\/p>\n<p>To process the string I use the <em>strtof()<\/em> function. This function is far superior to the old <em>atof()<\/em> function; <em>strtof()<\/em> uses two pointers, illustrated in Figure 1.<\/p>\n<div id=\"attachment_4527\" style=\"width: 560px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4527\" src=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2020\/12\/1208-figure1.png\" alt=\"\" width=\"550\" height=\"188\" class=\"size-full wp-image-4527\" srcset=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2020\/12\/1208-figure1.png 550w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2020\/12\/1208-figure1-300x103.png 300w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2020\/12\/1208-figure1-500x171.png 500w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><p id=\"caption-attachment-4527\" class=\"wp-caption-text\">Figure 1. How the <em>strtof()<\/em> function works<\/p><\/div>\n<p>The first pointer, <code>input<\/code>, references the string containing the value &mdash; and the value must come first. The second pointer, which is the address of a pointer (<code>convert<\/code> in my example), will hold the location of the first non-value character in the string, which comes in handy for plucking out the conversion characters.<\/p>\n<p>(I don&#8217;t cover the <em>strtof()<\/em> function specifically in this blog, though I do cover its relative <em>strtod()<\/em> in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=137\">this blog post<\/a>.)<\/p>\n<p>After input is read, this statement converts the value:<\/p>\n<p><code>w = strtof(input,&convert);<\/code><\/p>\n<p>Variable <code>w<\/code> holds the floating point value stored in string <code>input<\/code>, with pointer variable <code>convert<\/code> holding the location of the next character after the value. To ensure that the input was valid, a test is performed on w:<\/p>\n<p><code>\tif( w==0.0 && convert==input )<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;error_exit();<\/code><\/p>\n<p>When the value returned by <em>strtof()<\/em> is zero and both pointers are equal, the input contained no value. The code exits with an error message (<em>error_exit()<\/em>) when true.<\/p>\n<p>After converting and checking the value, another test is performed to ensure that two characters are typed after the value, where <code>convert<\/code> is a pointer referencing the first character:<\/p>\n<p><code>if( *convert=='\\0' ||<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;*convert=='\\n' ||<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;*(convert+1)=='\\0' ||<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;*(convert+1)=='\\n')<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;error_exit();<br \/>\n}<\/code><\/p>\n<p>At this point, I&#8217;m assured that two characters are found after the value, so a series of tests are performed to examine these characters and output the proper results. If anything goes awry during these tests, control is thrust to the <em>error_exit()<\/em> function, which terminates the code.<\/p>\n<p>Here is my solution:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_12-Exercise.c\" rel=\"noopener noreferrer\" target=\"_blank\">2020_12-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;ctype.h&gt;\r\n\r\nvoid error_exit(void)\r\n{\r\n    puts(\"Invalid input\");\r\n    exit(1);\r\n}\r\n\r\nint main()\r\n{\r\n    float w;\r\n    char input[16];\r\n    char *r,*convert;\r\n\r\n    <span class=\"comments\">\/* intro text *\/<\/span>\r\n    puts(\"Type a value to convert, suffixed by conversion types:\");\r\n    puts(\"K - kilos, P - pounds, S - stones\");\r\n    puts(\"Example: 2.0PK (convert 2.0 pounds to kilograms)\");\r\n    printf(\"Convert: \");\r\n\r\n    <span class=\"comments\">\/* gather input *\/<\/span>\r\n    r = fgets(input,16,stdin);\r\n    if( r==NULL )\r\n        error_exit();\r\n\r\n    <span class=\"comments\">\/* process input *\/<\/span>\r\n    w = strtof(input,&amp;convert);\r\n        <span class=\"comments\">\/* text for nothing input *\/<\/span>\r\n    if( w==0.0 &amp;&amp; convert==input )\r\n        error_exit();\r\n        <span class=\"comments\">\/* confirm that conversion characters exist *\/<\/span>\r\n    if( *convert=='\\0' ||\r\n        *convert=='\\n' ||\r\n        *(convert+1)=='\\0' ||\r\n        *(convert+1)=='\\n')\r\n    {\r\n        error_exit();\r\n    }\r\n        <span class=\"comments\">\/* kilo conversions *\/<\/span>\r\n    if( toupper(*convert)=='K' )\r\n    {\r\n        if( toupper( *(convert+1))=='P' )\r\n            printf(\"%.2f kilos is %.2f pounds\\n\",w,w*2.20462);\r\n        else if( toupper( *(convert+1))=='S' )\r\n            printf(\"%.2f kilos is %.2f stone\\n\",w,w*0.157473);\r\n        else\r\n            error_exit();\r\n    }\r\n        <span class=\"comments\">\/* pounds conversions *\/<\/span>\r\n    else if( toupper(*convert)=='P' )\r\n    {\r\n        if( toupper( *(convert+1))=='K' )\r\n            printf(\"%.2f pounds is %.2f kilos\\n\",w,w*0.453592);\r\n        else if( toupper( *(convert+1))=='S' )\r\n            printf(\"%.2f pounds is %.2f stone\\n\",w,w*0.0714286);\r\n        else\r\n            error_exit();\r\n    }\r\n        <span class=\"comments\">\/* stone conversions *\/<\/span>\r\n    else if( toupper(*convert)=='S' )\r\n    {\r\n        if( toupper( *(convert+1))=='K' )\r\n            printf(\"%.2f stone is %.2f kilos\\n\",w,w*6.35029);\r\n        else if( toupper( *(convert+1))=='P' )\r\n            printf(\"%.2f stone is %.2f pounds\\n\",w,w*14.0);\r\n        else\r\n            error_exit();\r\n    }\r\n    else\r\n        error_exit();\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>if-else if-else<\/em> monster scours for permutations of K, P, and S. Then a nested <em>if-else if-else<\/em> structure scans for the other letter and handles bogus input. Conversions are made within the <em>printf()<\/em> statements that output the results. Various <em>toupper()<\/em> functions translate lowercase letters to uppercase.<\/p>\n<p><code>Type a value to convert, suffixed by conversion types:<br \/>\nK - kilos, P - pounds, S - stones<br \/>\nExample: 2.0PK (convert 2.0 pounds to kilograms)<br \/>\nConvert: 103.5kp<br \/>\n103.50 kilos is 228.18 pounds<\/code><\/p>\n<p>In the sample run above, 103.5 kilograms is converted into pounds: 228.18.<\/p>\n<p>I hope your solution works and that proper output is generated.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This month&#8217;s Exercise is to create a program that converts weight measurements by using this format: nnnFT Where nnn is a value, F is the unit to convert from, and T is the unit to convert to. This problem is &hellip; <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4490\">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-4490","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\/4490","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=4490"}],"version-history":[{"count":9,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4490\/revisions"}],"predecessor-version":[{"id":4528,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4490\/revisions\/4528"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4490"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4490"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4490"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}