{"id":7320,"date":"2026-01-03T00:01:28","date_gmt":"2026-01-03T08:01:28","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7320"},"modified":"2025-12-27T16:05:28","modified_gmt":"2025-12-28T00:05:28","slug":"getting-and-setting-the-file-position-indicator","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7320","title":{"rendered":"Getting and Setting the File Position Indicator"},"content":{"rendered":"<p>As data is read from a file, a file position indicator (which most C references call a &#8220;file pointer&#8221;) moves sequentially through the file&#8217;s data. As a review, three functions are available to adjust this offset:<br \/>\n<!--more--><\/p>\n<ul>\n<li>The <em>ftell()<\/em> function returns the file position indicator&#8217;s current location as an offset within the file. (<a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1552\">Post<\/a>)<\/li>\n<li>The <em>fseek()<\/em> function manipulates the file position indicator&#8217;s value, thrusting it to a specific location in the file. (<a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1572\">Post<\/a>)<\/li>\n<li>The <em>rewind()<\/em> function resets the file position indicator back to the start of a file. (<a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1563\">Post<\/a>)<\/li>\n<\/ul>\n<p>These functions are particularly useful when performing random file access, such as fetching structures saved in a file or any time a file contains data organized in discrete chunks.<\/p>\n<p>Two more functions are available: <em>fgetpos()<\/em> and <em>fsetpos()<\/em>. The <em>fgetpos()<\/em> function returns the file position indicator&#8217;s location for an open file handle. The value is stored in a <em>fpos_t<\/em> structure. The <em>fsetpos()<\/em> function alters a file position&#8217;s location based on the values stored in a previously-created <em>fpos_t<\/em> structure. Here is the <em>man<\/em> page definition for <em>fgetpos()<\/em> and <em>fsetpos()<\/em>:<\/p>\n<p><code>int fgetpos(FILE *stream, fpos_t *pos);<br \/>\nint fsetpos(FILE *stream, const fpos_t *pos);<\/code><\/p>\n<p>The first argument is an open file stream. The second argument is the address of an <em>fpos_t<\/em> variable. The return value is zero upon success, with -1 returned otherwise and the <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1735\"><em>errno<\/em> value<\/a> set to indicate a specific error. Both functions are prototyped in the <code>stdio.h<\/code> header file.<\/p>\n<p>Unlike the other file manipulation functions, the <em>fpos_t<\/em> structure is the key to using <em>fgetpos()<\/em> and <em>fsetpos()<\/em>. This structure isn&#8217;t manipulated directly as its two members are named differently depending on the platform. But that&#8217;s not the point of these functions, which are best put to use when the value of the file position indicator must be retained and restored later without knowing its specific location.<\/p>\n<p>The following code uses these functions to read from the text file <a href=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2024\/08\/sonnet18.txt\" target=\"_new\" rel=\"noopener\"><code>sonnet18<\/code><\/a>.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_01_03-Lesson.c\" rel=\"noopener\" target=\"_blank\">2026_01_03-Lesson.c<\/a><\/h3>\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    const char filename[] = \"sonnet18.txt\";\r\n    FILE *fp;\r\n    int count,ch;\r\n    fpos_t pos;\r\n\r\n    <span class=\"comments\">\/* open the text file *\/<\/span>\r\n    fp = fopen(filename,\"r\");\r\n    if( fp==NULL )\r\n    {\r\n        fprintf(stderr,\"Unable to open %s\\n\",filename);\r\n        exit(1);\r\n    }\r\n    printf(\"%s opened\\n\",filename);\r\n\r\n    <span class=\"comments\">\/* read 256 bytes *\/<\/span>\r\n    count = 0;\r\n    while( count&lt;256 )\r\n    {\r\n        ch = fgetc(fp);\r\n        if( ch==EOF )\r\n            break;\r\n        putchar(ch);\r\n        count++;\r\n    }\r\n\r\n    <span class=\"comments\">\/* obtain the file position indicator position *\/<\/span>\r\n    puts(\"\\n\\n=== Getting file position indicator ===\\n\");\r\n    fgetpos(fp,&amp;pos);\r\n\r\n    <span class=\"comments\">\/* read another 256 bytes *\/<\/span>\r\n    count = 0;\r\n    while( count&lt;256 )\r\n    {\r\n        ch = fgetc(fp);\r\n        if( ch==EOF )\r\n            break;\r\n        putchar(ch);\r\n        count++;\r\n    }\r\n\r\n    <span class=\"comments\">\/* reset the file position indicator *\/<\/span>\r\n    puts(\"\\n\\n=== Resetting file position indicator ===\\n\");\r\n    fsetpos(fp,&amp;pos);\r\n\r\n    <span class=\"comments\">\/* read the rest of the file *\/<\/span>\r\n    while( (ch=fgetc(fp)) != EOF )\r\n        putchar(ch);\r\n\r\n    <span class=\"comments\">\/* clean-up *\/<\/span>\r\n    fclose(fp);\r\n    printf(\"%s closed\\n\",filename);\r\n    return 0;\r\n}<\/pre>\n<p>After the file is open, a <em>while<\/em> loop fetches and outputs the first 256 characters from the file. Then the <em>fgetpos()<\/em> function obtains the file position indicator&#8217;s location and saves is in <em>fpos_t<\/em> variable <code>pos<\/code>&#8216;s address: <code>fgetpos(fp,&amp;pos);<\/code><\/p>\n<p>A second <em>while<\/em> loop reads another 256 characters, outputting each. But then the <em>fsetpos()<\/em> function is called to restore the file position indicator: <code>fsetpos(fp,&pos);<\/code> The rest of the file is then output.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<pre>sonnet18.txt opened\r\nShall I compare thee to a summer's day?\r\nThou art more lovely and more temperate.\r\nRough winds do shake the darling buds of May,\r\nAnd summer's lease hath all too short a date.\r\nSometime too hot the eye of heaven shines,\r\nAnd often is his gold complexion dimmed;\r\n\r\n=== Getting file position indicator ===\r\n\r\n\r\nAnd every fair from fair sometime declines,\r\nBy chance, or nature's changing course, untrimmed;\r\nBut thy eternal summer shall not fade,\r\nNor lose possession of that fair thou ow'st,\r\nNor shall death brag thou wand'rest in his shade,\r\nWhen in eternal lines to T\r\n\r\n=== Resetting file position indicator ===\r\n\r\n\r\nAnd every fair from fair sometime declines,\r\nBy chance, or nature's changing course, untrimmed;\r\nBut thy eternal summer shall not fade,\r\nNor lose possession of that fair thou ow'st,\r\nNor shall death brag thou wand'rest in his shade,\r\nWhen in eternal lines to Time thou grow'st.\r\n  So long as men can breathe, or eyes can see,\r\n  So long lives this, and this gives life to thee.\r\nsonnet18.txt closed<\/pre>\n<p>Of course, for this example I know that the file position indicator is at 256 characters when it&#8217;s saved. But the true purpose of the <em>fgetpos(<\/em>) and <em>fsetpos()<\/em> functions is to obtain and restore an unknown offset. And, yes, it&#8217;s valid to argue that <em>ftell()<\/em> and <em>fseek()<\/em> can be used in a similar manner. Even so, these functions are available as an alternative.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Add two more functions to the roundup of those that manipulate how a file is read. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7320\">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-7320","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\/7320","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=7320"}],"version-history":[{"count":10,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7320\/revisions"}],"predecessor-version":[{"id":7345,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7320\/revisions\/7345"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7320"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7320"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}