{"id":3096,"date":"2018-05-08T00:01:38","date_gmt":"2018-05-08T07:01:38","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=3096"},"modified":"2018-05-05T13:03:11","modified_gmt":"2018-05-05T20:03:11","slug":"translating-a-timestamp-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3096","title":{"rendered":"Translating a Timestamp &#8211; Solution"},"content":{"rendered":"<p>Your task for <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=3071\">this month&#8217;s Exercise<\/a> is to take a timestamp string and move values from inside a string (characters) into a structure. It&#8217;s not an easy exercise, and it doesn&#8217;t have a single, best solution.<br \/>\n<!--more--><br \/>\nHere is the sample string, with date and time values buried inside:<\/p>\n<p><code>\"2018_05_15 12:18:22\"<\/code><\/p>\n<p>Assume that the string retains the same format for any date. So one approach, the first one I tried, would be to calculate the offsets for each value within the string:<\/p>\n<p><code>year = 0;<br \/>\nmonth = 5;<br \/>\nyear = 8;<br \/>\nhour = 11;<br \/>\nminute = 14;<br \/>\nsecond = 17;<\/code><\/p>\n<p>Every value other than the <code>year<\/code> is just two-digits long. You can use these consistent offset values to reference inside the string and extract the two-digit values. That&#8217;s what I did for my solution, but I was disappointed because it had a lot of overhead.<\/p>\n<p>For my second approach, I noticed that the string separates each of the values with a single character. The character is either an underscore, space, or a colon, yet these characters are non-digits. Therefore, I can plow the string and replace any non-digit value with a null character, <code>\\0<\/code>. The result is a buffer that contains tiny little strings, each of a significant value. Here&#8217;s how I did that:<\/p>\n<pre><code>while(timestamp[x])\r\n{   \r\n    if(!isdigit(timestamp[x]))\r\n        timestamp[x] = '\\0';\r\n    x++;\r\n}<\/code><\/pre>\n<p>The <em>isdigit()<\/em> function returns TRUE when the character <code>timestamp[x]<\/code> is a digit, 0 through 9. The <code>!<\/code> (not) negates that condition, meaning the <em>if<\/em> statement is true for non-digits. If so, the non-digit character at <code>timestamp[x]<\/code> is replaced with the null character. The effect is to slice-up the string into smaller chunks, tiny strings of digits inside a character buffer.<\/p>\n<p>Once the string is sliced up, I can use a pointer to stop at each non-null character and translate that mini-string into an integer value.<\/p>\n<p>To march through the buffer, I initialize a pointer variable, <code>offset<\/code>, to the base of <code>timestamp[]<\/code>:<\/p>\n<p><code>offset = timestamp;<\/code><\/p>\n<p>The first item is the year, which is extracted into the <code>datetime<\/code> structure <code>ts<\/code>:<\/p>\n<p><code>ts.year = atoi(offset);<\/code><\/p>\n<p>After obtaining that value, a <em>while<\/em> statement increments the <code>offset<\/code> pointer until it encounters a null character:<\/p>\n<p><code>while(*(offset++));<\/code><\/p>\n<p>Because variable <code>offset<\/code> is post-incremented, its address references a digit inside the buffer after the <em>while<\/em> loop stops. At that point, I use the <em>atoi()<\/em> function to convert the mini-string into an integer value, then store the value in the relevant <code>ts<\/code> structure&#8217;s member.<\/p>\n<p>Here is the full code:<\/p>\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\nint main()\r\n{\r\n    char timestamp[] = \"2018_05_15 12:18:22\";\r\n    struct datetime {\r\n        int year;\r\n        int month;\r\n        int day;\r\n        int hour;\r\n        int minute;\r\n        int second;\r\n    } ts;\r\n    char *offset;\r\n    int x = 0;\r\n\r\n    printf(\"Time stamp string is '%s'\\n\",timestamp);\r\n\r\n    <span class=\"comments\">\/* replace non-digits with null chars *\/<\/span>\r\n    while(timestamp[x])\r\n    {\r\n        if(!isdigit(timestamp[x]))\r\n            timestamp[x] = '\\0';\r\n        x++;\r\n    }\r\n\r\n    offset = timestamp;\r\n    ts.year = atoi(offset);\r\n    while(*(offset++));\r\n    ts.month = atoi(offset);\r\n    while(*(offset++));\r\n    ts.day = atoi(offset);\r\n    while(*(offset++));\r\n    ts.hour = atoi(offset);\r\n    while(*(offset++));\r\n    ts.minute = atoi(offset);\r\n    while(*(offset++));\r\n    ts.second = atoi(offset);\r\n\r\n    printf(\"Timestamp structure is %d %d %d %d %d %d\\n\",\r\n            ts.year,\r\n            ts.month,\r\n            ts.day,\r\n            ts.hour,\r\n            ts.minute,\r\n            ts.second\r\n          );\r\n\r\n    return(0);\r\n}<\/pre>\n<p>This solution proved more elegant than my original effort (which I didn&#8217;t save). Still I think it&#8217;s clunky: The clutch of statements between Lines 29 and 40 could be replaced with something better. Perhaps you came up with a solution that looks pretty and works properly. If so, great!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Your task for this month&#8217;s Exercise is to take a timestamp string and move values from inside a string (characters) into a structure. It&#8217;s not an easy exercise, and it doesn&#8217;t have a single, best solution.<\/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-3096","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\/3096","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=3096"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3096\/revisions"}],"predecessor-version":[{"id":3107,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3096\/revisions\/3107"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3096"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3096"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3096"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}