{"id":3671,"date":"2019-07-13T00:01:46","date_gmt":"2019-07-13T07:01:46","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3671"},"modified":"2019-07-06T10:08:10","modified_gmt":"2019-07-06T17:08:10","slug":"putting-strtol-to-the-test","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3671","title":{"rendered":"Putting <em>strtol()<\/em> to the Test"},"content":{"rendered":"<p>Stop using the <em>atoi(<\/em>) function! Yes, it&#8217;s a golden oldie, often my go-to function for converting strings to integers, but it&#8217;s weak. The <em>strtol()<\/em> function, on the other hand, not only converts strings to integers, it can validate input as well.<br \/>\n<!--more--><br \/>\nFor truly secure code, it helps to know whether the user input the value 0 as a string or input nonsense interpreted as zero. How can you tell?<\/p>\n<p>Well, you could write a routine that looks at the input string to determine if the first character is <code>'0'<\/code> &mdash; or the second character if the user is cheeky enough to type <code>\"+0\"<\/code> or <code>\"-0\"<\/code>, which are both valid forms of input for the value zero. Such overhead isn&#8217;t necessary, however, when you use the <em>strtol()<\/em> function.<\/p>\n<p>The second argument of <em>strtol()<\/em> is a pointer. When <code>NULL<\/code> is specified, the argument is ignored. Otherwise, you can set a pointer as the argument and compare that pointer&#8217;s address with the start of the input string to determine whether the text input was legitimately interpreted as zero.<\/p>\n<p>Before showing you the code, be aware that the <em>strtol()<\/em> function ignores any leading whitespace characters before a value. The characters + and &#8211; are interpreted as sign operators. And prefix values are also interpreted, for example <code>0x<\/code> for a hexadecimal value (providing that the third argument in the function is 16). When the string begins with text, or the string is empty, the value zero is returned &mdash; which is a legitimate result, but not exactly what the user supplied.<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nint main()\r\n{\r\n    char x[] = \"nonsense\";\r\n    char *p;\r\n    int a;\r\n\r\n    a = strtol(x,&amp;p,10);\r\n    printf(\"'%s' evaluates to %d\\n\",x,a);\r\n    if( p == x )\r\n    {\r\n        printf(\"'%s' doesn't contain any values\\n\",x);\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>At Line 6, string <code>x<\/code> is assigned to a string of all text, not a number. The <em>strtol()<\/em> function at Line 10 converts the string into the value zero, which is stored in variable <code>a<\/code>. However, because pointer <code>p<\/code> is specified as an argument in the <em>strtol()<\/em> function, the zero value can be verified.<\/p>\n<p>At Line 12, the address stored in variable <code>p<\/code> is compared with the start of the string <code>x<\/code>. If both values are equal, the zero return value is invalid; the string doesn&#8217;t contain legitimate numeric input.<\/p>\n<p>Here&#8217;s a test run:<\/p>\n<p><code>'nonsense' evaluates to 0<br \/>\n'nonsense' doesn't contain any values<\/code><\/p>\n<p>Change Line 6 to read <code>char x[] = \"\";<\/code>, and the output becomes:<\/p>\n<p><code>'' evaluates to 0<br \/>\n'' doesn't contain any values<\/code><\/p>\n<p>The empty string is properly interpreted as not being zero; the input is invalid.<\/p>\n<p>Change the string to <code>\"0\"<\/code>, and the output is:<\/p>\n<p><code>'0' evaluates to 0<\/code><\/p>\n<p>The <em>strtol()<\/em> function legitimately found zero as input.<\/p>\n<p>Finally, to prove the <em>strtol()<\/em> function&#8217;s worth beyond nonsense values and zero, I changed Line 6 again to read:<\/p>\n<p><code>char x[] = \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+789\";<\/code><\/p>\n<p>The <em>strtol()<\/em> function ignores the leading whitespace, the sign value is interpreted properly, and the value is converted into an integer. Here&#8217;s a sample run:<\/p>\n<p><code>'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+789' evaluates to 789<\/code><\/p>\n<p>When teaching C, I default to the <em>atoi()<\/em> function, which is simple to understand. For advanced courses, however, I use <em>strtol()<\/em>. And when writing the most secure code, especially for mission-critical input functions, I use the pointer argument and verify the input. You should too.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The <em>strtol()<\/em> function not only converts strings to integers, it helps you validate the input data. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3671\">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-3671","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\/3671","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=3671"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3671\/revisions"}],"predecessor-version":[{"id":3680,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3671\/revisions\/3680"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3671"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3671"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}