{"id":1857,"date":"2016-04-08T00:01:03","date_gmt":"2016-04-08T07:01:03","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=1857"},"modified":"2016-04-02T10:07:08","modified_gmt":"2016-04-02T17:07:08","slug":"read-a-percentage-value-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=1857","title":{"rendered":"Read a Percentage Value &#8211; Solution"},"content":{"rendered":"<p>One of the things I enjoy about coding defensive input is that I get to think about all the oddball possibilities. Users can type anything, which is something you must always anticipate. For typing in a percentage value, the door for whacky input is left wide open.<br \/>\n<!--more--><br \/>\nMy solution to <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1816\">this month&#8217;s Exercise<\/a> relies on two C library functions: <em>fgets()<\/em> to read input and <em>strtof()<\/em> to convert a string to a <em>float<\/em> value. The bulk of my solution is to get from one function to the other and strip out any oddball user input between.<\/p>\n<p>Once the string is obtained by <em>fgets()<\/em>, I pass it along to a <em>read_percent()<\/em> function:<\/p>\n<pre><code>float read_percent(char *percent);<\/code><\/pre>\n<p>The function accepts a string <code>percent<\/code> as an argument and returns a <em>float<\/em> value equal to the percentage in the string. The string can contain the % and , symbols, along with the decimal separator. Any other characters that might invalidate are dealt with by the <em>strtof()<\/em> function directly.<\/p>\n<p>Inside the <em>read_percent()<\/em> function, two things happen:<\/p>\n<ol>\n<li>The percent character (%) is scanned for and, if located, translated to a newline (<code>\\n<\/code>).<\/li>\n<p> Because the % might be found at the end of input, that translation works.<\/p>\n<li>Any commas encountered are removed from the string. So the value <strong>1,000<\/strong> would translate to <strong>1000<\/strong>, which the <em>strtof()<\/em> function can easily digest. Otherwise, a comma would truncate input, and <strong>1,000<\/strong> would be read as <strong>1<\/strong>.<\/li>\n<\/ol>\n<p>The code could also strip the newline (<code>\\n<\/code>) from the input string, which I normally do for <em>fgets()<\/em> function input, but the <em>strtof()<\/em> function doesn&#8217;t give a rip about the newline character, so it&#8217;s good.<\/p>\n<p>Here is my solution:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\n#define SIZE 32\r\n\r\nfloat read_percent(char *percent);\r\n\r\nint main()\r\n{\r\n    char input[SIZE];\r\n    float p;\r\n\r\n    printf(\"Enter a percentage: \");\r\n    fgets(input,SIZE,stdin);\r\n    p = read_percent(input);\r\n    printf(\"I'm working with a value of %.2f percent\\n\",p);\r\n\r\n    return(0);\r\n}\r\n\r\nfloat read_percent(char *percent)\r\n{\r\n    int i,j;\r\n    char new[SIZE] = \"\\0\";\r\n\r\n    <span class=\"comments\">\/* strip out a percent sign *\/<\/span>\r\n    i = 0;\r\n    while( *(percent+i) )\r\n    {\r\n        if( *(percent+i) == '%' )\r\n            *(percent+i) = '\\n';\r\n        i++;\r\n    }\r\n\r\n    <span class=\"comments\">\/* strip off commas *\/<\/span>\r\n    i = j = 0;\r\n    while( *(percent+i) != '\\0')\r\n    {\r\n        if( *(percent+i) != ',' )\r\n        {\r\n            *(new+j) = *(percent+i);\r\n            j++;\r\n        }\r\n        i++;\r\n    }\r\n\r\n    return( strtof(new,NULL) );\r\n}<\/pre>\n<p>The <em>char<\/em> buffer <code>new<\/code> is created and initialized at Line 24. It&#8217;s required for the comma-stripping portion of the function.<\/p>\n<p>At Line 26, the code scans for the % character in the input string <code>percent<\/code>. If found, the character is replaced with a newline, <code>\\n<\/code>, at Line 30. If for some reason the user types <strong>%50<\/strong> instead of <strong>50%<\/strong>, then the input is invalid anyway, so the value returned is 0.00, which is okay.<\/p>\n<p>Lines 35 through 45 strip out any commas in the input string. Characters are read from string <code>percent<\/code>. If the character isn&#8217;t a comma (Line 39), it&#8217;s copied  to string <code>new<\/code> and  both offset variables, <code>i<\/code> and <code>j<\/code>, are incremented. Otherwise, only offset variable <code>i<\/code> is incremented, effectively skipping the comma character.<\/p>\n<p>After the string is copied, the result is sent to the <em>strtof()<\/em> function. The result is immediately returned at Line 47.<\/p>\n<p>My solution presents only one possibility. I&#8217;m sure many others exist. In fact, you could strip out both the percent and comma characters in a single loop, which would make the <em>read_percent()<\/em> function tighter. As long as your solution defensively handles a variety of different input strings, you&#8217;re good.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the things I enjoy about coding defensive input is that I get to think about all the oddball possibilities. Users can type anything, which is something you must always anticipate. For typing in a percentage value, the door &hellip; <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1857\">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-1857","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\/1857","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=1857"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1857\/revisions"}],"predecessor-version":[{"id":1870,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1857\/revisions\/1870"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1857"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1857"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1857"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}