file bug

Discussion in 'C Programming' started by Bill Cunningham, Feb 18, 2008.

  1. I have written this file and decided to try error checking and eof
    checking and there must be a bug somewhere. It compiled with djgpp fine. It
    takes the win32/pe assembler as.exe and writes it to a.exe. I hope it's not
    too hard to read. I'm stumped but that's expected and nothing new.

    #include <stdio.h>
    #include <stdlib.h>

    main(){
    char buf [2048];
    FILE *fp;
    fp=fopen("as.exe","rb");
    if (fread(buf,sizeof(char),2048,fp)!=2048)
    {if (ferror(fp))
    {fprintf(stderr,"File error"); exit(1);}
    if (feof(fp)) {fprintf(stderr,"EOF error"); exit (1);}}
    fclose(fp);
    fp=fopen("a.exe","wb");
    fwrite(buf,sizeof(char),2048,fp);
    fclose(fp);}

    stdlib.h for exit()

    Bill
     
    Bill Cunningham, Feb 18, 2008
    #1
    1. Advertising

  2. Oh yes I deliberately wrote it to fail. It only read 2048 bytes and the
    file is about 202k.

    Bill
     
    Bill Cunningham, Feb 18, 2008
    #2
    1. Advertising

  3. Bill Cunningham wrote:
    > I have written this file and decided to try error checking and eof
    > checking and there must be a bug somewhere. It compiled with djgpp fine. It
    > takes the win32/pe assembler as.exe and writes it to a.exe. I hope it's not
    > too hard to read. I'm stumped but that's expected and nothing new.
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > main(){
    > char buf [2048];
    > FILE *fp;
    > fp=fopen("as.exe","rb");
    > if (fread(buf,sizeof(char),2048,fp)!=2048)
    > {if (ferror(fp))
    > {fprintf(stderr,"File error"); exit(1);}
    > if (feof(fp)) {fprintf(stderr,"EOF error"); exit (1);}}


    This is certainly not what you intend to do, unless you are
    somehow magically guaranteed that the file when read magically fills a
    2048 byte buffer without remainder.
    On reaching end-of-file you want to write out the buffer and close the
    output file. You do _not_ want to call it an error and abort.

    And your use of exit(1) is not portable. The only portably defined
    values for exit are 0, EXIT_SUCCESS, and EXIT_FAILURE. None of them
    need be equal to 1.
     
    Martin Ambuhl, Feb 18, 2008
    #3

  4. > This is certainly not what you intend to do, unless you are
    > somehow magically guaranteed that the file when read magically fills a
    > 2048 byte buffer without remainder.


    What can I do about this? If I wanted to read a file that is 200k or one
    that is 300mB? Do you always have to look at the file to see how big it is?

    > On reaching end-of-file you want to write out the buffer and close the
    > output file. You do _not_ want to call it an error and abort.
    >
    > And your use of exit(1) is not portable. The only portably defined values
    > for exit are 0, EXIT_SUCCESS, and EXIT_FAILURE. None of them need be
    > equal to 1.


    I wanted to overflow this program and test the eof or error checking.

    Bill
     
    Bill Cunningham, Feb 18, 2008
    #4
  5. Would the answer to reading a file of unknown size involve fseek() and
    or fpos() ?

    I also wanted this file to crash and it certainly didn't. So I'm asking two
    questions here.

    1) How can I get a file like the one I wrote to fail so I would see
    fprintf(stderr,"EOF error");

    2) How would you read into buffer the size of a file when the size is
    unknown? fseek() or fpos() involved ?

    Bill
     
    Bill Cunningham, Feb 18, 2008
    #5
  6. > Would the answer to reading a file of unknown size involve fseek() and
    >or fpos() ?


    Often, you keep reading bytes until you hit the end of file. No
    seeking involved. Hitting end of file is *not* usually considered
    an error; it is expected you'll hit it eventualy. You might hit
    end of file at an unexpected place, e.g. in the middle of a C
    comment and consider that an error.

    >I also wanted this file to crash and it certainly didn't. So I'm asking two
    >questions here.


    Files don't crash, programs crash. And hitting end of file isn't
    normally considered a "crash", and a program hitting that shouldn't
    react with a crash.

    >1) How can I get a file like the one I wrote to fail so I would see
    >fprintf(stderr,"EOF error");


    Keep reading in a loop, stopping only when you get EOF or an error.

    >2) How would you read into buffer the size of a file when the size is
    >unknown? fseek() or fpos() involved ?


    Keep enlarging the buffer (with realloc()). When you get end-of-file,
    reduce the size of the buffer to the size of all the data actually
    read. Or read the file in pieces and never try to have the whole
    file in memory at one time.
     
    Gordon Burditt, Feb 18, 2008
    #6

  7. > Keep enlarging the buffer (with realloc()). When you get end-of-file,
    > reduce the size of the buffer to the size of all the data actually
    > read. Or read the file in pieces and never try to have the whole
    > file in memory at one time.


    So this is the step for reading a file til EOF and saving it to another
    name? Basically cp or copy a 'to' b ?

    Bill
     
    Bill Cunningham, Feb 18, 2008
    #7
  8. Bill Cunningham

    MisterE Guest

    "Bill Cunningham" <> wrote in message
    news:THmuj.1206$JF.1043@trnddc01...
    >
    >> This is certainly not what you intend to do, unless you are
    >> somehow magically guaranteed that the file when read magically fills a
    >> 2048 byte buffer without remainder.

    >
    > What can I do about this? If I wanted to read a file that is 200k or
    > one that is 300mB? Do you always have to look at the file to see how big
    > it is?


    You can easily get the size of a file:
    FILE *in;
    char *filedata;
    long size_in_bytes;
    in=fopen("file.txt","rb");
    fseek(in,0,SEEK_END);
    size_in_bytes = ftell(in);
    fseek(in,0,SEEK_SET);
    filedata = malloc(size_in_bytes);
    fread(in,sizeof(char),size_in_bytes);



    >> On reaching end-of-file you want to write out the buffer and close the
    >> output file. You do _not_ want to call it an error and abort.
    >>
    >> And your use of exit(1) is not portable. The only portably defined
    >> values for exit are 0, EXIT_SUCCESS, and EXIT_FAILURE. None of them need
    >> be equal to 1.

    >
    > I wanted to overflow this program and test the eof or error checking.
    >
    > Bill
    >
    >
     
    MisterE, Feb 18, 2008
    #8
  9. Bill Cunningham

    MisterE Guest

    "Bill Cunningham" <> wrote in message
    news:qGkuj.4290$0%3.2142@trnddc06...
    > Oh yes I deliberately wrote it to fail. It only read 2048 bytes and the
    > file is about 202k.


    What do you mean it doesn't fail? Why should it it says to read 2k and write
    2k. It will do that and end.
     
    MisterE, Feb 18, 2008
    #9

  10. > Keep enlarging the buffer (with realloc()). When you get end-of-file,
    > reduce the size of the buffer to the size of all the data actually
    > read. Or read the file in pieces and never try to have the whole
    > file in memory at one time.


    So I'll need a buffer for fread and write.
    char buff(10);
    And a pointer for realloc
    char *b=&buff;
    Something like that right?

    Bill
     
    Bill Cunningham, Feb 18, 2008
    #10
  11. Bill Cunningham

    Guest

    On Feb 19, 12:45 am, "Bill Cunningham" <> wrote:
    > > Keep enlarging the buffer (with realloc()). When you get end-of-file,
    > > reduce the size of the buffer to the size of all the data actually
    > > read. Or read the file in pieces and never try to have the whole
    > > file in memory at one time.

    >
    > So I'll need a buffer for fread and write.
    > char buff(10);
    > And a pointer for realloc
    > char *b=&buff;
    > Something like that right?

    No, not something like that, and you know it.
    It is not a learning issue when you have 'char buf(10);' or 'char
    *b=&buff' in your code.
    It's a matter of lazyness or you are trying to troll. It wouldn't
    compile.
    You want to raise discussions over why would one put a whole file in
    memory or why ftell() is not reliable et cetera.

    As it's been told to you before: either put the whole file in memory
    OR read it in chunks/blocks.
    Do not further ask here how to do that, go read about
    malloc(),realloc(),fread(),fseek(),ftell() (the latter two, you don't
    even need)
    If you don't understand what these functions do or return, don't ask
    here, read about them again.

    And in your future posts, please avoid mentioning assemblers, file
    formats and operating systems.
    That is, if you are not troll.
     
    , Feb 18, 2008
    #11
  12. MisterE said:

    >
    > "Bill Cunningham" <> wrote in message
    > news:THmuj.1206$JF.1043@trnddc01...
    >>
    >>> This is certainly not what you intend to do, unless you are
    >>> somehow magically guaranteed that the file when read magically fills a
    >>> 2048 byte buffer without remainder.

    >>
    >> What can I do about this? If I wanted to read a file that is 200k or
    >> one that is 300mB? Do you always have to look at the file to see how big
    >> it is?

    >
    > You can easily get the size of a file:
    > FILE *in;
    > char *filedata;
    > long size_in_bytes;
    > in=fopen("file.txt","rb");


    What if fopen returns NULL?

    > fseek(in,0,SEEK_END);


    SEEK_END is not guaranteed to be meaningful for binary files.

    > size_in_bytes = ftell(in);
    > fseek(in,0,SEEK_SET);
    > filedata = malloc(size_in_bytes);


    What if malloc returns NULL?

    > fread(in,sizeof(char),size_in_bytes);


    fread takes more than three parameters.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Feb 19, 2008
    #12
  13. >> Keep enlarging the buffer (with realloc()). When you get end-of-file,
    >> reduce the size of the buffer to the size of all the data actually
    >> read. Or read the file in pieces and never try to have the whole
    >> file in memory at one time.

    >
    > So this is the step for reading a file til EOF and saving it to another
    >name? Basically cp or copy a 'to' b ?


    A more usual way to copy a file is to read a chunk of it into a
    buffer, then write the number of bytes you read to the copy. Repeat
    (re-using the same buffer) until you get end-of-file trying to read
    more data. What's a "chunk"? Any size you want, from one byte to
    billions of terabytes, provided your system can handle it.

    For efficient copies, a buffer size of one or a few disk blocks
    (e.g. 512 bytes to 16Kbytes on common systems available today) might
    work better than waiting to read the whole (terabyte) file before
    writing any of it.
     
    Gordon Burditt, Feb 19, 2008
    #13
  14. Bill Cunningham

    MisterE Guest


    >
    > SEEK_END is not guaranteed to be meaningful for binary files.


    Why exactally doesn't it work?
    I know C99 7.19.9.2 says:

    A binary stream need not meaningfully support fseek calls
    with a whence value of SEEK_END.

    I know the standard says it need not, but so what? 99.9999% of compilers do,
    and those that don't probably don't support fseek at all.
     
    MisterE, Feb 19, 2008
    #14
  15. MisterE said:

    >
    >>
    >> SEEK_END is not guaranteed to be meaningful for binary files.

    >
    > Why exactally doesn't it work?


    On platforms where it works, of course it /does/ work. But the Standard
    mentions the possibility that it may fail because there really are
    implementations where it /does/ fail because of the way the filesystem
    works (basically, some filesystems put an arbitrary amount of padding at
    the end of a file).

    > I know C99 7.19.9.2 says:
    >
    > A binary stream need not meaningfully support fseek calls
    > with a whence value of SEEK_END.
    >
    > I know the standard says it need not, but so what? 99.9999% of compilers
    > do, and those that don't probably don't support fseek at all.


    Well, I question your 99.9999%, since there are probably something like a
    hundred or so mainstreamish C compilers out there, of which a small
    handful (one? two? four? nine? who knows?) don't provide meaningful
    support for SEEK_END on binary files. If your code never has to run on any
    of these implementations, then yes, sure, so what? But if it ever does
    have to, then of course it matters. Obviously you know your user base
    better than I do, so you're in a better position than I am to judge
    whether you need to be this cautious.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Feb 19, 2008
    #15
  16. On 18 Feb, 18:59, "Bill Cunningham" <> wrote:

    >     I have written this file and decided to try error checking


    but you failed to check if the fopen() calls succeeded

    > and eof
    > checking and there must be a bug somewhere.


    you suffer from the illusion that EOF is an error.

    > It compiled with djgpp fine. It
    > takes the win32/pe assembler as.exe and writes it to a.exe. I hope it's not
    > too hard to read.


    your layout is horrid


    > I'm stumped but that's expected and nothing new.


    <snip code>

    in later posts you ask how to copy a file and don't
    seem to understand the answer.

    in pcode:

    LOOP UNTIL NO MORE DATA
    read;
    write;
    END


    in C

    #include <stdio.h>
    #include <stdlib.h>

    int main(void)
    {
    char buf [2048];
    FILE *fp_in;
    FILE *fp_out;
    size_t ch_read;

    if ((fp_in = fopen ("as.exe", "rb")) == NULL)
    {
    fprintf (stderr, "failed to open input file\n");
    exit (EXIT_FAILURE);
    }

    if ((fp_out = fopen ("a.exe", "wb")) == NULL)
    {
    fprintf (stderr, "failed to open output file\n");
    fclose (fp_in);
    exit (EXIT_FAILURE);
    }

    do
    {
    if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
    sizeof(buf)
    && ferror(fp_in))
    {
    fprintf (stderr, "read error\n");
    fclose (fp_in);
    fclose (fp_out);
    exit (EXIT_FAILURE);
    }

    if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
    {
    fprintf (stderr, "write error\n");
    fclose (fp_in);
    fclose (fp_out);
    exit (EXIT_FAILURE);
    }
    }
    while (ch_read == sizeof(buf));

    fclose (fp_in);
    fclose (fp_out);

    return 0;
    }


    this compiles and runs without error but is otherwise untested.
    Oh, the output file is the same size as the input file.


    --
    Nick Keighley

    A ruby trembled. Two tourmaline nets failed to rectify the laser beam.
    A diamond noted the error. Both the error and the correction went into
    the general computer.
    Corwainer Smith "The Dead Lady of Clown Town"
     
    Nick Keighley, Feb 19, 2008
    #16
  17. Bill Cunningham

    Default User Guest

    Nick Keighley wrote:

    > On 18 Feb, 18:59, "Bill Cunningham" <> wrote:
    >
    > > I have written this file and decided to try error checking

    >
    > but you failed to check if the fopen() calls succeeded


    This is an example of why I stopped dealing with Bill. He had a
    previous problem using file-handling, and I wanted him to work on that
    exercise until it was complete and he understood all the aspects of the
    functions he was trying to use. He refused, and skipped off to a series
    of other problems, NONE of which he's come anywhere close to working
    satisfactorily.

    He's wasting eveyone's time. Whether he's a long-con troll or truly
    learning-disabled doesn't matter. If it's the latter, then everyone
    just has to accept that programming is not for him. He doesn't show any
    capability to concentrate on a problem long enough to complete it.

    He could study C for a hundred years and not be a capable practicioner.
    Not every endeavor is for every person. He either needs to follow the
    instructions of the people here or give up.




    Brian
     
    Default User, Feb 19, 2008
    #17
  18. in pcode:

    LOOP UNTIL NO MORE DATA
    read;
    write;
    END


    in C

    #include <stdio.h>
    #include <stdlib.h>

    int main(void)
    {
    char buf [2048];
    FILE *fp_in;
    FILE *fp_out;
    size_t ch_read;

    if ((fp_in = fopen ("as.exe", "rb")) == NULL)
    {
    fprintf (stderr, "failed to open input file\n");
    exit (EXIT_FAILURE);
    }

    if ((fp_out = fopen ("a.exe", "wb")) == NULL)
    {
    fprintf (stderr, "failed to open output file\n");
    fclose (fp_in);
    exit (EXIT_FAILURE);
    }

    do
    {
    if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
    sizeof(buf)
    && ferror(fp_in))
    {
    fprintf (stderr, "read error\n");
    fclose (fp_in);
    fclose (fp_out);
    exit (EXIT_FAILURE);
    }

    if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
    {
    fprintf (stderr, "write error\n");
    fclose (fp_in);
    fclose (fp_out);
    exit (EXIT_FAILURE);
    }
    }
    while (ch_read == sizeof(buf));

    fclose (fp_in);
    fclose (fp_out);

    return 0;
    }


    this compiles and runs without error but is otherwise untested.
    Oh, the output file is the same size as the input file.


    Whoa. Wow that's a lot of code I'll copy and try to digest it. I don't
    see enough simple code to get readily. I've never seen do used for this and
    never used it myself. I'll compile and study it thanks.

    Bill
     
    Bill Cunningham, Feb 19, 2008
    #18

  19. > You can easily get the size of a file:
    > FILE *in;
    > char *filedata;
    > long size_in_bytes;
    > in=fopen("file.txt","rb");
    > fseek(in,0,SEEK_END);
    > size_in_bytes = ftell(in);
    > fseek(in,0,SEEK_SET);
    > filedata = malloc(size_in_bytes);
    > fread(in,sizeof(char),size_in_bytes);
    >
    >
    >
    >>> On reaching end-of-file you want to write out the buffer and close the
    >>> output file. You do _not_ want to call it an error and abort.
    >>>
    >>> And your use of exit(1) is not portable. The only portably defined
    >>> values for exit are 0, EXIT_SUCCESS, and EXIT_FAILURE. None of them
    >>> need be equal to 1.


    Ok thanks I need to see as much simple code as I can. All that I seem to
    get hold of is written in shorthand and such.

    Bill
     
    Bill Cunningham, Feb 19, 2008
    #19
  20. [snip]

    #include <stdio.h>
    #include <stdlib.h>

    int main(void)
    {
    char buf [2048];
    FILE *fp_in;
    FILE *fp_out;
    size_t ch_read; /*cool. */

    if ((fp_in = fopen ("as.exe", "rb")) == NULL)
    {
    fprintf (stderr, "failed to open input file\n");
    exit (EXIT_FAILURE);
    }

    if ((fp_out = fopen ("a.exe", "wb")) == NULL)
    {
    fprintf (stderr, "failed to open output file\n");
    fclose (fp_in);
    exit (EXIT_FAILURE);
    }

    do
    {
    if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
    sizeof(buf)

    absolutlely brillant. I always wondered how to deal with these return
    values. Since fread returns a size_t declare a size_t to hold the return
    value and use = to assign. Other than the fp=fopen example I haven't seen
    this much. Not in code that I can read.

    && ferror(fp_in))
    {
    fprintf (stderr, "read error\n");
    fclose (fp_in);
    fclose (fp_out);
    exit (EXIT_FAILURE);
    }

    if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
    {
    fprintf (stderr, "write error\n");
    fclose (fp_in);
    fclose (fp_out);
    exit (EXIT_FAILURE);
    }
    }
    while (ch_read == sizeof(buf));

    fclose (fp_in);
    fclose (fp_out);

    return 0;
    }


    this compiles and runs without error but is otherwise untested.
    Oh, the output file is the same size as the input file.


    I'll tell you I can read very little of any C code I come across because
    it's written by people who know what they're doing and they take shortcuts
    in writing and it just leaves me in the dust. This I can make out enough to
    not be just confused and actually learn a little.

    Bill
     
    Bill Cunningham, Feb 19, 2008
    #20
    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. John

    Re: BUG? OR NOT A BUG?

    John, Sep 20, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    582
  2. RedEye
    Replies:
    2
    Views:
    610
    Jason Kester
    Dec 13, 2005
  3. Michel Joly de Lotbiniere

    Bug Parade Bug 4953793

    Michel Joly de Lotbiniere, Nov 30, 2003, in forum: Java
    Replies:
    4
    Views:
    662
    Michel
    Dec 2, 2003
  4. DarkSpy
    Replies:
    4
    Views:
    909
    tom_usenet
    Jun 27, 2003
  5. Alan Davies
    Replies:
    7
    Views:
    225
    Alan Davies
    Nov 27, 2003
Loading...

Share This Page