Can the current file position indicator ever be greater the actual file size?

Discussion in 'C Programming' started by Andrew, Sep 30, 2003.

  1. Andrew

    Andrew Guest

    Hello,

    Is it possible for a file position indicator of an input stream to be
    greater than the size of a file? And if so could this cause fgetc to
    somehow write to the file? For example is it possible to continually
    call fgetc past the size of the file and cause some type of undefined
    behavior? Thanks
     
    Andrew, Sep 30, 2003
    #1
    1. Advertising

  2. Andrew

    nrk Guest

    Re: Can the current file position indicator ever be greater the actualfile size?

    Andrew wrote:
    > Hello,
    >
    > Is it possible for a file position indicator of an input stream to be
    > greater than the size of a file?


    Size of a file is vague (as in there's no such thing in standard C). It
    is not possible to advance the file position indicator once the end of
    file indicator is set.

    > And if so could this cause fgetc to
    > somehow write to the file? For example is it possible to continually
    > call fgetc past the size of the file and cause some type of undefined
    > behavior? Thanks


    A conforming implementation of fgetc will advance the file position
    indicator only if the end of file indicator is not set, and it seems
    unlikely that it will modify the underlying stream. Hence, not possible.

    -nrk.
     
    nrk, Sep 30, 2003
    #2
    1. Advertising

  3. Andrew

    Andrew Guest

    (Andrew) wrote in message news:<>...
    > Hello,
    >
    > Is it possible for a file position indicator of an input stream to be
    > greater than the size of a file? And if so could this cause fgetc to
    > somehow write to the file? For example is it possible to continually
    > call fgetc past the size of the file and cause some type of undefined
    > behavior? Thanks


    Sorry, Let me try to re-phrase this with a simple example. The
    following code writes the letter A and an additional 10 bytes (1 for
    each call to fgetc) to the output file . I am wondering why this
    happens and if there is a way I can avoid it. I don't believe fflush
    is suppose to be used on this type of stream? Although, I tried
    fflush(of) and it worked, but I suspect it would have wiped out any
    previous information which the file contained that I might want to
    preserve. Thanks for any advice.

    #include <stdio.h>

    int main() {

    FILE *of;
    int i;

    if((of = fopen("c:\\problem.txt", "w")) == NULL) {
    if((of = fopen("c:\\problem.txt", "r+")) == NULL) {
    printf("\nFile Error");
    }
    }

    /* Without a fputc call before the loop the problem does
    not exist */

    fputc(65,of);

    /* tried fflush(of) here but I think this is undefined?
    and it seems to clear any previous contents
    stored before program execution */

    /* 10 can be replaced with any number larger than the
    input file size */
    for(i = 0; i < 10; i++)
    fgetc(of);

    fclose(of);

    return 0;

    }
     
    Andrew, Sep 30, 2003
    #3
  4. Andrew wrote:

    > Sorry, Let me try to re-phrase this with a simple example. The
    > following code writes the letter A and an additional 10 bytes (1 for
    > each call to fgetc) to the output file . I am wondering why this
    > happens and if there is a way I can avoid it. I don't believe fflush
    > is suppose to be used on this type of stream? Although, I tried
    > fflush(of) and it worked, but I suspect it would have wiped out any
    > previous information which the file contained that I might want to
    > preserve. Thanks for any advice.
    >
    > #include <stdio.h>
    >
    > int main() {
    >
    > FILE *of;
    > int i;
    >
    > if((of = fopen("c:\\problem.txt", "w")) == NULL) {
    > if((of = fopen("c:\\problem.txt", "r+")) == NULL) {


    This looks a bit scary, but it basically says "if I can't create it, I want
    to open it read-write instead". If that's what you want, then fair enough.

    > printf("\nFile Error");
    > }
    > }
    >
    > /* Without a fputc call before the loop the problem does
    > not exist */
    >
    > fputc(65,of);


    This doesn't write 'A', by the way - it writes whatever character happens to
    have the value 65 on the system you're running it on. (Let me guess - 'A'
    on your system, right? But on, say, an IBM mainframe, you'd get a different
    result.)

    fputc('A', of); conveys your intent more clearly /and/ is portable.

    >
    > /* tried fflush(of) here but I think this is undefined?


    No, you're fine with fflush() on streams open for output or update.

    > and it seems to clear any previous contents
    > stored before program execution */


    That's not fflush()'s fault. That's your "w" mode talking (remember those
    fopen() calls above?). Swap it around with your "r+".

    >
    > /* 10 can be replaced with any number larger than the
    > input file size */
    > for(i = 0; i < 10; i++)
    > fgetc(of);


    If the file was successfully created ("w" mode), there's nothing to read, is
    there? So fgetc() will return EOF, to indicate that it couldn't fulfil your
    request. I note that your program is not checking the return value of
    fgetc. If you add a check, you will find that fgetc is returning EOF on
    each call.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Oct 1, 2003
    #4
  5. Andrew

    Jack Klein Guest

    On 30 Sep 2003 15:47:19 -0700, (Andrew) wrote in
    comp.lang.c:

    > (Andrew) wrote in message news:<>...
    > > Hello,
    > >
    > > Is it possible for a file position indicator of an input stream to be
    > > greater than the size of a file? And if so could this cause fgetc to
    > > somehow write to the file? For example is it possible to continually
    > > call fgetc past the size of the file and cause some type of undefined
    > > behavior? Thanks

    >
    > Sorry, Let me try to re-phrase this with a simple example. The
    > following code writes the letter A and an additional 10 bytes (1 for
    > each call to fgetc) to the output file . I am wondering why this
    > happens and if there is a way I can avoid it. I don't believe fflush
    > is suppose to be used on this type of stream? Although, I tried
    > fflush(of) and it worked, but I suspect it would have wiped out any
    > previous information which the file contained that I might want to
    > preserve. Thanks for any advice.
    >
    > #include <stdio.h>
    >
    > int main() {
    >
    > FILE *of;
    > int i;
    >
    > if((of = fopen("c:\\problem.txt", "w")) == NULL) {
    > if((of = fopen("c:\\problem.txt", "r+")) == NULL) {
    > printf("\nFile Error");
    > }
    > }
    >
    > /* Without a fputc call before the loop the problem does
    > not exist */
    >
    > fputc(65,of);
    >
    > /* tried fflush(of) here but I think this is undefined?
    > and it seems to clear any previous contents
    > stored before program execution */
    >
    > /* 10 can be replaced with any number larger than the
    > input file size */
    > for(i = 0; i < 10; i++)
    > fgetc(of);
    >
    > fclose(of);
    >
    > return 0;
    >
    > }


    You are breaking a rule of the C library, and so you are causing
    undefined behavior:

    "When a file is opened with update mode ('+' as the second or third
    character in the above list of mode argument values), both input and
    output may be performed on the associated stream. However, output
    shall not be directly followed by input without an intervening call to
    the fflush function or to a file positioning function (fseek,
    fsetpos, or rewind), and input shall not be directly followed by
    output without an intervening call to a file positioning function,
    unless the input operation encounters endof-file."

    When you use fputc() and then use fgetc() without calling a
    file-seeking function in between, you are violating a "shall" clause
    outside of a constraint section. The result is undefined behavior
    which can be anything, as far as C is concerned, including putting
    things in your file that you do not want.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
     
    Jack Klein, Oct 1, 2003
    #5
  6. Andrew

    Jack Klein Guest

    On 30 Sep 2003 15:47:19 -0700, (Andrew) wrote in
    comp.lang.c:

    > (Andrew) wrote in message news:<>...
    > > Hello,
    > >
    > > Is it possible for a file position indicator of an input stream to be
    > > greater than the size of a file? And if so could this cause fgetc to
    > > somehow write to the file? For example is it possible to continually
    > > call fgetc past the size of the file and cause some type of undefined
    > > behavior? Thanks

    >
    > Sorry, Let me try to re-phrase this with a simple example. The
    > following code writes the letter A and an additional 10 bytes (1 for
    > each call to fgetc) to the output file . I am wondering why this
    > happens and if there is a way I can avoid it. I don't believe fflush
    > is suppose to be used on this type of stream? Although, I tried
    > fflush(of) and it worked, but I suspect it would have wiped out any
    > previous information which the file contained that I might want to
    > preserve. Thanks for any advice.
    >
    > #include <stdio.h>
    >
    > int main() {
    >
    > FILE *of;
    > int i;
    >
    > if((of = fopen("c:\\problem.txt", "w")) == NULL) {
    > if((of = fopen("c:\\problem.txt", "r+")) == NULL) {
    > printf("\nFile Error");
    > }
    > }
    >
    > /* Without a fputc call before the loop the problem does
    > not exist */
    >
    > fputc(65,of);
    >
    > /* tried fflush(of) here but I think this is undefined?
    > and it seems to clear any previous contents
    > stored before program execution */
    >
    > /* 10 can be replaced with any number larger than the
    > input file size */
    > for(i = 0; i < 10; i++)
    > fgetc(of);
    >
    > fclose(of);
    >
    > return 0;
    >
    > }


    You are breaking a rule of the C library, and so you are causing
    undefined behavior:

    "When a file is opened with update mode ('+' as the second or third
    character in the above list of mode argument values), both input and
    output may be performed on the associated stream. However, output
    shall not be directly followed by input without an intervening call to
    the fflush function or to a file positioning function (fseek,
    fsetpos, or rewind), and input shall not be directly followed by
    output without an intervening call to a file positioning function,
    unless the input operation encounters endof-file."

    When you use fputc() and then use fgetc() without calling a
    file-seeking function in between, you are violating a "shall" clause
    outside of a constraint section. The result is undefined behavior
    which can be anything, as far as C is concerned, including putting
    things in your file that you do not want.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
     
    Jack Klein, Oct 1, 2003
    #6
  7. Andrew

    Avinash Guest

    (Andrew) wrote in message news:<>...
    > Hello,
    >
    > Is it possible for a file position indicator of an input stream to be
    > greater than the size of a file? And if so could this cause fgetc to
    > somehow write to the file? For example is it possible to continually
    > call fgetc past the size of the file and cause some type of undefined
    > behavior? Thanks




    If the end-of-file indicator for the input stream pointed to by stream
    is not set and a next byte is present, the fgetc() function shall
    obtain the next byte as an unsigned char converted to an int, from the
    input stream pointed to by stream, and advance the associated file
    position indicator for the stream (if defined). Since fgetc() operates
    on bytes, reading a character consisting of multiple bytes (or "a
    multi-byte character") may require multiple calls to fgetc().
     
    Avinash, Oct 1, 2003
    #7
  8. Andrew

    Andrew Guest

    Thanks everyone for your advice. I was not aware of the consequences
    involved with omitting a file seeking call in between these types of
    file operations. I apologize for posting a question that could have
    easily found out from further reading, but I think I had been looking
    in the wrong direction for the root of the problem. This advice along
    with clarification on the open file mode I was using helped alot.
    Thanks again.
     
    Andrew, Oct 1, 2003
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jason
    Replies:
    25
    Views:
    1,005
    Jorge Rivera
    Feb 22, 2004
  2. lazy

    string size greater than page size?

    lazy, Apr 27, 2007, in forum: C Programming
    Replies:
    3
    Views:
    381
    Army1987
    Apr 27, 2007
  3. Jason
    Replies:
    0
    Views:
    219
    Jason
    Jul 6, 2004
  4. Daniel Berger

    Getting the actual size of a sparse file

    Daniel Berger, Jan 5, 2011, in forum: Ruby
    Replies:
    9
    Views:
    276
    Johan Holmberg
    Jan 6, 2011
  5. Replies:
    37
    Views:
    345
    Dennis Lee Bieber
    Oct 25, 2013
Loading...

Share This Page