{"id":1572,"date":"2015-10-03T00:01:56","date_gmt":"2015-10-03T07:01:56","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=1572"},"modified":"2025-12-13T10:12:54","modified_gmt":"2025-12-13T18:12:54","slug":"abuse-the-file-position-indicator","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=1572","title":{"rendered":"Abuse the File Position Indicator"},"content":{"rendered":"<p>Files can be read sequentially or you can hop around, reading this chunk or that chunk, which is how random file access works. Internally, however, it&#8217;s all just file access. The difference between sequential and random file access is how the file position indicator is abused.<br \/>\n<!--more--><br \/>\nThe traditional file position indicator abuse functions are <em>ftell()<\/em>, <em>fseek()<\/em>, and <em>rewind()<\/em>. I covered <em>ftell()<\/em> in the <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1552\">September 12 Lesson<\/a>, and <em>rewind()<\/em> was covered <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1563\">last week<\/a>. Now it&#8217;s time for <em>fseek()<\/em>.<\/p>\n<p>The <em>fseek()<\/em> function is the random access function. For example, when reading structures to a file you can use <em>fseek()<\/em> to set the file position indicator to read a specific structure in the file. The <em>fread()<\/em> function fetches the structure&#8217;s chunk-o-info. Here&#8217;s the format for <em>fseek()<\/em>:<\/p>\n<p><code>fseek(<em>handle<\/em>,<em>offset<\/em>,<em>whence<\/em>)<\/code><\/p>\n<p><em>handle<\/em> is the file pointer for an open file.<\/p>\n<p><em>offset<\/em> is a <em>long int<\/em> value for the number of bytes relative to the <em>whence<\/em> position, the spot where the file position indicator is moved. This value can be positive or negative.<\/p>\n<p><em>whence<\/em> is one of three constants, <code>SEEK_SET<\/code>, <code>SEEK_CUR<\/code>, or <code>SEEK_END<\/code> for the start of the file, current file indicator position, or the end of the file, respectively.<\/p>\n<p>In the following code, <em>fseek()<\/em> reads and outputs the last 10 characters of the file <a href=\"http:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2015\/09\/gettysburg.txt\">gettysburg.txt<\/a> and then reads and outputs the first 10 characters of the file.<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\nint main()\r\n{\r\n    FILE *fh;\r\n    int c,x;\r\n\r\n    <span class=\"comments\">\/* open the file *\/<\/span>\r\n    fh = fopen(\"gettysburg.txt\",\"r\");\r\n    if(fh == NULL)\r\n    {\r\n        perror(\"Unable to open file\\n\");\r\n        return(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* read the last 10 bytes *\/<\/span>\r\n    printf(\"Last 10 bytes: \");\r\n    fseek(fh,-10,SEEK_END);\r\n    while( (c=fgetc(fh)) != EOF)\r\n        putchar(c);\r\n\r\n    <span class=\"comments\">\/* read the first 10 bytes *\/<\/span>\r\n    printf(\"First 10 bytes: \");\r\n    fseek(fh,0,SEEK_SET);\r\n    for(x=0;x<10;x++)\r\n        putchar(fgetc(fh));\r\n    putchar('\\n');\r\n\r\n    fclose(fh);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>fseek()<\/em> function at Line 18 positions the file indicator to 10 bytes (characters) before the EOF. The value -10 and <code>SEEK_END<\/code> set that position.<\/p>\n<p>At Line 24, the <em>fseek()<\/em> function is pinch-hitting for <em>rewind()<\/em>. In effect, the <em>fseek()<\/em> function in that specific format works the same as <em>rewind()<\/em>.<\/p>\n<p>Here's sample output:<\/p>\n<pre><code>Last 10 bytes: d equal.\r\n\r\nFirst 10 bytes: Four score<\/code><\/pre>\n<p>Given what you know about <em>fseek()<\/em>, how would you concoct code to read the middle 10 bytes of a file?<\/p>\n<p>The <em>fseek()<\/em> function doesn't have a <em>whence<\/em> position for the file's center. So how could you determine the file's overall size, split that in two, and then position the file indicator to read the middle 10 bytes of a file?<\/p>\n<p>Yes, this is a Lesson, not an Exercise, so while you could rush off and attempt to figure out a solution on your own (and thank you for trying), my solution is this:<\/p>\n<p>Set the file position indicator to the end of the file with <code>fseek(fh,0,SEEK_END)<\/code>, then use <em>ftell()<\/em> to get that position value. Divide it by 2, then use <em>fseek()<\/em> to set the center location and read 10 characters.<\/p>\n<p>Here's the chunk of code I added to the above listing at Line 29, also after declaring an <em>int<\/em> variable <code>middle<\/code>:<\/p>\n<pre class=\"screen\">\r\n    <span class=\"comments\">\/* read the middle 10 bytes *\/<\/span>\r\n    fseek(fh,0,SEEK_END);\r\n    middle = ftell(fh) \/ 2;\r\n    fseek(fh,middle-5,SEEK_SET);\r\n    printf(\"Middle 10 bytes: \");\r\n    for(x=0;x<10;x++)\r\n        putchar(fgetc(fh));\r\n    putchar('\\n');<\/pre>\n<p><a href=\"http:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2015\/10\/1003b.c\">Click here<\/a> to download or view the modified source code.<\/p>\n<p>Here is the new output:<\/p>\n<pre><code>Last 10 bytes: d equal.\r\n\r\nFirst 10 bytes: Four score\r\nMiddle 10 bytes: tion, conc<\/code><\/pre>\n<p>The true power of <em>fseek()<\/em>, however, is in its capability to fetch a file organized into specific chunks, i.e., random access. I'll demonstrate that technique in <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1583\">next week's Lesson<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use the <em>fseek()<\/em> function to change how a file is read. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1572\">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-1572","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\/1572","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=1572"}],"version-history":[{"count":8,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1572\/revisions"}],"predecessor-version":[{"id":7319,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1572\/revisions\/7319"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}