{"id":3363,"date":"2018-11-17T00:01:38","date_gmt":"2018-11-17T08:01:38","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3363"},"modified":"2018-11-24T08:41:07","modified_gmt":"2018-11-24T16:41:07","slug":"reading-and-writing-structures-to-a-file","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3363","title":{"rendered":"Reading and Writing Structures to a File"},"content":{"rendered":"<p>You need not read all structures from a file when you know the exact one you want. To fetch that record, you use the <em>fseek()<\/em> function. This function manipulates the file position indicator, allowing for random access to a file&#8217;s data.<br \/>\n<!--more--><br \/>\nFrom <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3357\">last week&#8217;s Lesson<\/a>, I setup code that wrote five <code>person<\/code> structures to a file, <code>family.data<\/code>. Run the code from that lesson to create the file that&#8217;s used for this Lesson.<\/p>\n<p>Knowing that the file <code>family.data<\/code> contains five <code>person<\/code> structures, I can use the <em>fseek()<\/em> function to set the file position indicator and read a specific record (structure) stored in the file. Here&#8217;s how the <em>fseek()<\/em> function is defined:<\/p>\n<p><code>int fseek(FILE *stream, long offset, int whence);<\/code><\/p>\n<p><code>*stream<\/code> is the handle of an open file. It can be opened for reading, writing, or both.<\/p>\n<p><code>offset<\/code> is the location where the file position indicator is set.<\/p>\n<p><code>whence<\/code> references where the <code>offset<\/code> argument is measured from; it&#8217;s not always the start of the file. Constants <code>SEEK_SET<\/code>, <code>SEEK_CUR<\/code>, and <code>SEEK_END<\/code> represent the start of the file, current file position indicator location, and the end of the file, respectively.<\/p>\n<p><a href=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2018\/11\/1117a.c\">Click here<\/a> to view sample code that fetches a specific record from the family.data file. The key to the code is the <em>fseek()<\/em> statement at Line 30:<\/p>\n<p><code>fseek(fp, (record-1)*sizeof(struct person), SEEK_SET);<\/code><\/p>\n<p>Variable <code>fp<\/code> is the <code>FILE<\/code> pointer. <code>record<\/code> is the structure to be read (input as values 1 through 5). The <em>sizeof<\/em> operator is used on <code>struct person<\/code> to fetch its size in bytes, which is how the offset is calculated. Constant <code>SEEK_SET<\/code> directs the function to look from the start of the file.<\/p>\n<p>After setting the file position indicator, an <em>fread()<\/em> function fetches the structure from the file. The code displays the results. Here&#8217;s a sample run:<\/p>\n<p><code>Fetch which record (1 to 5)? 4<br \/>\nRecord 4:<br \/>\nName: Missy<br \/>\nAge: 12<br \/>\nWeight: 80.2<\/code><\/p>\n<p>Say that Missy had a birthday and she&#8217;s now 13. To update her record in the file, you first read in her record. In memory, the record is modified, updating the <code>age<\/code> member of the <code>person<\/code> structure. Then that record is written back to the same position in the file. The file position pointer must be set to initially read the specific record and set again to write it back to the same location within the file.<\/p>\n<p><a href=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2018\/11\/1117b.c\">Click here<\/a> to view the code that updates a record in the file. Constant <code>RECORD<\/code> is set to the record to fetch, 3, which is Missy&#8217;s structure array element. Here&#8217;s the <em>fseek()<\/em> statement, which repeats three times in the code:<\/p>\n<p><code>fseek(fp, RECORD*sizeof(struct person), SEEK_SET);<\/code><\/p>\n<p>The first time is to position the record to be read. The second time is to position the updated record to be written. And the final time is to read back in the record to confirm that the change was made.<\/p>\n<p>Here is the output:<\/p>\n<p><code>Record 4:<br \/>\nName: Missy<br \/>\nAge: 12<br \/>\nWeight: 80.2<br \/>\nRecord updated:<br \/>\nRecord 4:<br \/>\nName: Missy<br \/>\nAge: 13<br \/>\nWeight: 80.2<\/code><\/p>\n<p>Random file access allows you to fetch and put portions of a file, which is far more efficient than processing the entire file, manipulating it in memory, then writing it back out. To perform random file access, you need not open the file in any special manner; just use the <em>fseek()<\/em> function to set the file position indicator, and you&#8217;re doing random file access.<\/p>\n<p>One issue that arises with structures and files is pointers. When the structure is a pointer or contains pointers, you must ensure that you write the data to the file and not the pointer&#8217;s address. I address this issue in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3373\">next week&#8217;s Lesson<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Accessing individual structures within a file provides an excellent example of random file access. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3363\">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-3363","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\/3363","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=3363"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3363\/revisions"}],"predecessor-version":[{"id":3391,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3363\/revisions\/3391"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}