{"id":2379,"date":"2017-02-25T00:01:16","date_gmt":"2017-02-25T08:01:16","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=2379"},"modified":"2017-02-18T09:40:18","modified_gmt":"2017-02-18T17:40:18","slug":"yes-its-a-string-or-number","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=2379","title":{"rendered":"Yes! It&#8217;s a String &#8211; or Number!"},"content":{"rendered":"<p>The standard library functions <em>atoi()<\/em> and <em>atof()<\/em> work well to translate text (ASCII) input into values, an <em>int<\/em> or <em>float<\/em>, respectively. When your code must know whether a string is really a value, more processing is required.<br \/>\n<!--more--><br \/>\nThe first method I&#8217;ve used to confirm values is a simple comparison: The original string is compared with the translated value. If they match, then the translation is successful and the proper value was obtained. This method uses the <em>atoi()<\/em> and <em>atof()<\/em> functions as well as <em>sprintf()<\/em> and <em>strcmp()<\/em> to compare the results. Here&#8217;s sample code based on <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=2351\">last week&#8217;s Lesson<\/a>&#8216;s example:<\/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 main()\r\n{\r\n    char *strings[4] = {\r\n        \"123\",\r\n        \"0.33\",\r\n        \"7lucky\",\r\n        \"string\"\r\n    };\r\n    int asint;\r\n    float asfloat;\r\n    char buffer[16];\r\n\r\n    for(int x=0;x&lt;4;x++)\r\n    {\r\n        printf(\"String \\\"%s\\\"\\n\",strings[x]);\r\n        <span class=\"comments\">\/* test int comparison *\/<\/span>\r\n        asint = atoi(strings[x]);\r\n        sprintf(buffer,\"%d\",asint);\r\n        if(strcmp(buffer,strings[x])==0)\r\n            printf(\"\\tString matches as int: \\\"%s\\\" == \\\"%s\\\"\\n\",\r\n                    strings[x],\r\n                    buffer\r\n                  );\r\n        else\r\n            printf(\"\\tString doesn't match as int: \\\"%s\\\" != \\\"%s\\\"\\n\",\r\n                    strings[x],\r\n                    buffer\r\n                  );\r\n       <span class=\"comments\">\/* test float comparison *\/<\/span>\r\n        asfloat = atof(strings[x]);\r\n        sprintf(buffer,\"%f\",asfloat);\r\n        if(strcmp(buffer,strings[x])==0)\r\n            printf(\"\\tString matches as float: \\\"%s\\\" == \\\"%s\\\"\\n\",\r\n                    strings[x],\r\n                    buffer\r\n                  );\r\n        else\r\n            printf(\"\\tString doesn't match as float: \\\"%s\\\" != \\\"%s\\\"\\n\",\r\n                    strings[x],\r\n                    buffer\r\n                  );\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>For each string in the <code>strings[]<\/code> array, <em>atio(<\/em>) and <em>atof()<\/em> translate. The <em>sprintf()<\/em> function takes the resulting value and converts it back into a string. Then that converted string, <code>buffer<\/code>, is compared with the original string.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<pre><code>String \"123\"\r\n\tString matches as int: \"123\" == \"123\"\r\n\tString doesn't match as float: \"123\" != \"123.000000\"\r\nString \"0.33\"\r\n\tString doesn't match as int: \"0.33\" != \"0\"\r\n\tString doesn't match as float: \"0.33\" != \"0.330000\"\r\nString \"7lucky\"\r\n\tString doesn't match as int: \"7lucky\" != \"7\"\r\n\tString doesn't match as float: \"7lucky\" != \"7.000000\"\r\nString \"string\"\r\n\tString doesn't match as int: \"string\" != \"0\"\r\n\tString doesn't match as float: \"string\" != \"0.000000\"<\/code><\/pre>\n<p>As you can see, this method works best on <em>int<\/em> values. The problem with <em>float<\/em> comparisons is that the decimal positions are wrong: values <code>0.33<\/code> and <code>0.330000<\/code> are identical, but not as strings.<\/p>\n<p>Another way to process text input as a value is to crunch through the string and determine its value based on individual characters. The following code uses the <em>value_type()<\/em> function to guess a string&#8217;s numeric type:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;ctype.h&gt;\r\n\r\nint value_type(char *s)\r\n{\r\n    enum { FALSE, TRUE };\r\n    int f_flag = FALSE;\r\n\r\n    while(*s)\r\n    {\r\n        if(*s == '.')\r\n        {\r\n            f_flag = TRUE;\r\n            s++;\r\n        }\r\n        else if(!isdigit(*s))\r\n        {\r\n            return(0);  <span class=\"comments\">\/* text *\/<\/span>\r\n        }\r\n        else\r\n        {\r\n            s++;\r\n        }\r\n    }\r\n\r\n    if(f_flag)\r\n        return(1);  <span class=\"comments\">\/* float *\/<\/span>\r\n\r\n    return(2);  <span class=\"comments\">\/* int *\/<\/span>\r\n}\r\n\r\nint main()\r\n{\r\n    char *strings[4] = {\r\n        \"123\",\r\n        \"0.33\",\r\n        \"7lucky\",\r\n        \"string\"\r\n    };\r\n    int t;\r\n\r\n    for(int x=0;x&lt;4;x++)\r\n    {\r\n        printf(\"String \\\"%s\\\" is probably a\",strings[x]);\r\n        t = value_type(strings[x]);\r\n        switch(t)\r\n        {\r\n            case 2:\r\n                printf(\"n integer\\n\");\r\n                break;\r\n            case 1:\r\n                printf(\" float\\n\");\r\n                break;\r\n            case 0:\r\n                printf(\" string\\n\");\r\n                break;\r\n            default:\r\n                printf(\"Undefined\\n\");\r\n        }\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>value_type()<\/em> function reads the input string one character at a time. If a <code>'.'<\/code> is found, the <code>f_flag<\/code> variable is set to TRUE. That character is found in a float. After that character is eliminated, the <em>isdigit()<\/em> function is used to reject any string that doesn&#8217;t contain a digit.<\/p>\n<p>After the string is processed, an <em>if<\/em> statement tests the <code>f_flag<\/code> variable. If TRUE, that means the string is all numbers with a period, so the value 1 is returned to represent a <em>float<\/em>. Otherwise, the value 2 is returned for an <em>int<\/em>.<\/p>\n<p>In the <em>main()<\/em> function, a <em>switch-case<\/em> structure evaluates the return value <code>t<\/code> from function <em>value_type()<\/em>. Here&#8217;s sample output:<\/p>\n<pre><code>String \"123\" is probably an integer\r\nString \"0.33\" is probably a float\r\nString \"7lucky\" is probably a string\r\nString \"string\" is probably a string<\/code><\/pre>\n<p>One thing I didn&#8217;t do in this code was to test for the presence of more than one period in a number. While it would be rare to have input such as <code>\"1.234.56\"<\/code> the code should anticipate such a thing. You can modify the <em>value_type()<\/em> function to test for multiple <code>'.'<\/code> characters in a string and then evaluate such input as a string as opposed to a <em>float<\/em>.<\/p>\n<p>Further, the code could also test for and eliminate commas <code>','<\/code> in a string, just in case the user is dorky enough to specify them as a thousands separator.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Two ways to test whether a string represents a value or it&#8217;s just a silly old string. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=2379\">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-2379","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\/2379","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=2379"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2379\/revisions"}],"predecessor-version":[{"id":2387,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2379\/revisions\/2387"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2379"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2379"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2379"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}