{"id":3346,"date":"2018-11-03T00:01:21","date_gmt":"2018-11-03T07:01:21","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3346"},"modified":"2018-10-27T11:28:47","modified_gmt":"2018-10-27T18:28:47","slug":"reading-and-writing-raw-data","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3346","title":{"rendered":"Reading and Writing Raw Data"},"content":{"rendered":"<p>From your early C language training, you should know the difference between 1088 as a string and 1088 as an integer. They may look the same to human eyes, but inside the computer they&#8217;re completely different.<br \/>\n<!--more--><br \/>\nThe string 1088 is composed of five character values: 1, 0, 8, 8, and the null character <code>\\0<\/code> to terminate the string.<\/p>\n<p>The integer value 1088 is stored as a bit pattern in two or more bytes.<\/p>\n<p>The good news is that you can code with either implementation of 1088, converting between string and integer as you go. For file I\/O, 1088 must be written and read as a string or written and read as raw data for the process to the successful. You can&#8217;t switch between the two. This rule works out well because different file I\/O functions are used to write strings and raw data.<\/p>\n<p>For writing and reading raw-data, two file I\/O functions are <em>fwrite()<\/em> and <em>fread()<\/em>. These both work with a file handle returned from a successful <em>fopen()<\/em> function. Both functions are prototyped in the <code>stdio.h<\/code> header file and both have similar arguments:<\/p>\n<p><code>size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);<br \/>\nsize_t fwrite(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);<\/code><\/p>\n<p><code>void *restric ptr<\/code> is fancy talk for the address of the item to be written to a file. If the item isn&#8217;t a pointer, affix the <code>&<\/code> (address-of) operator to the variable&#8217;s name.<\/p>\n<p><code>size_t size<\/code> is the size of the item written or read, as expressed in bytes. For example, if you&#8217;re writing an integer value, you would put the operator <code>sizeof(int)<\/code> to get the proper size value.<\/p>\n<p><code>size_t nitems<\/code> is the number of items to write. So if you&#8217;re writing an array of 4 <em>double<\/em> values, the <code>nitems<\/code> argument would be 4.<\/p>\n<p><code>FILE *restict stream<\/code> is the pointer variable returned from a successful <em>fopen()<\/em> statement.<\/p>\n<p>The value returned is the number of bytes written to or read from the file.<\/p>\n<p>The following code is similar to the example from <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3337\">last week&#8217;s Lesson<\/a>, though integer value 1088 is written and read instead of the string 1088:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    const char filename[] = \"highscore.dat\";\r\n    int score = 1088;\r\n    FILE *hs;\r\n\r\n    <span class=\"comments\">\/* create the file and write the value *\/<\/span>\r\n    printf(\"Writing high score: %d\\n\",score);\r\n    hs = fopen(filename,\"w\");\r\n    if( hs == NULL)\r\n    {\r\n        fprintf(stderr,\"Error writing to %s\\n\",filename);\r\n        return(1);\r\n    }\r\n    fwrite(&amp;score, sizeof(int), 1, hs);\r\n    fclose(hs);\r\n\r\n    <span class=\"comments\">\/* open the file and read the value *\/<\/span>\r\n    hs = fopen(filename,\"r\");\r\n    if( hs == NULL)\r\n    {\r\n        fprintf(stderr,\"Error reading from  %s\\n\",filename);\r\n        return(1);\r\n    }\r\n    fread(&amp;score, sizeof(int), 1, hs);\r\n    printf(\"Reading high score: %d\\n\",score);\r\n    fclose(hs);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Only Lines 17 and 27 are different between this code and the example shown last week. These are the <em>fwrite()<\/em> and <em>fread()<\/em> functions. But the data written to the file is completely different, despite the output being exactly the same:<\/p>\n<p><code>Writing high score: 1088<br \/>\nReading high score: 1088<\/code><\/p>\n<p>Here&#8217;s the file&#8217;s raw data, courtesy of the <em>hexdump<\/em> utility:<\/p>\n<pre><code>00000000  40 04 00 00                                       |@...|\r\n00000004<\/code><\/pre>\n<p>The four raw bytes (the size of an <em>int<\/em>) appear in the file, not the characters 1, 0, 8, and 8. And the data was read back into the <code>score<\/code> variable cleanly, without the need to convert between a string and <em>int<\/em>.<\/p>\n<p>In next week&#8217;s Lesson, I begin to explore random file access.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Unlike working with text in a file, working with raw data requires using special file I\/O functions. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3346\">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-3346","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\/3346","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=3346"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3346\/revisions"}],"predecessor-version":[{"id":3359,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3346\/revisions\/3359"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}