fread/fwrite 2

Discussion in 'C Programming' started by Bill Cunningham, Jun 23, 2012.

  1. Ok after looking a Nick's old post again, I decided to try my own
    copy. It seems to fill better with my style. Now it compiles can
    copies fine. The thing is it hasn't been tested as to whether or not
    it copied actual 2048 bytes at a time. I will submit it for review...

    #include <stdio.h>

    int main()
    {
    size_t nread = 0;
    char buf[2048];
    FILE *fpi, *fpo;
    if ((fpi = fopen("t", "rb")) == NULL)
    return -1;
    if ((fpo = fopen("z", "wb")) == NULL)
    return -2;
    do {
    nread = fread(buf, sizeof(buf), 1, fpi);
    if (ferror(fpi))
    return -3;
    fwrite(buf, sizeof(buf), nread, fpo);
    if (ferror(fpo))
    return -4;
    }
    while (!feof(fpi));
    fclose(fpi);
    fclose(fpo);
    return 0;
    }
     
    Bill Cunningham, Jun 23, 2012
    #1
    1. Advertising

  2. On Jun 23, 4:31 pm, Bill Cunningham <> wrote:
    > Ok after looking a Nick's old post again, I decided to try my own
    > copy. It seems to fill better with my style. Now it compiles can
    > copies fine. The thing is it hasn't been tested as to whether or not
    > it copied actual 2048 bytes at a time. I will submit it for review...
    >
    > #include <stdio.h>
    >
    > int main()
    > {
    >     size_t nread = 0;
    >     char buf[2048];
    >     FILE *fpi, *fpo;
    >     if ((fpi = fopen("t", "rb")) == NULL)
    >         return -1;
    >     if ((fpo = fopen("z", "wb")) == NULL)
    >         return -2;
    >     do {
    >         nread = fread(buf, sizeof(buf), 1, fpi);
    >         if (ferror(fpi))
    >             return -3;
    >         fwrite(buf, sizeof(buf), nread, fpo);
    >         if (ferror(fpo))
    >             return -4;
    >     }
    >     while (!feof(fpi));
    >     fclose(fpi);
    >     fclose(fpo);
    >     return 0;
    >
    >
    >
    > }- Hide quoted text -
    >
    > - Show quoted text -


    Ok I guess there must be a short count somewhere in this code. Most of
    it has been copied I get no errors and I must admit I'm a little
    stumped. It's got to be in the fread fwrite system somehow.

    B
     
    Bill Cunningham, Jun 23, 2012
    #2
    1. Advertising

  3. On Jun 23, 4:31 pm, Bill Cunningham <> wrote:
    > Ok after looking a Nick's old post again, I decided to try my own
    > copy. It seems to fill better with my style. Now it compiles can
    > copies fine. The thing is it hasn't been tested as to whether or not
    > it copied actual 2048 bytes at a time. I will submit it for review...
    >
    > #include <stdio.h>
    >
    > int main()
    > {
    >     size_t nread = 0;
    >     char buf[2048];
    >     FILE *fpi, *fpo;
    >     if ((fpi = fopen("t", "rb")) == NULL)
    >         return -1;
    >     if ((fpo = fopen("z", "wb")) == NULL)
    >         return -2;
    >     do {
    >         nread = fread(buf, sizeof(buf), 1, fpi);
    >         if (ferror(fpi))
    >             return -3;
    >         fwrite(buf, sizeof(buf), nread, fpo);
    >         if (ferror(fpo))
    >             return -4;
    >     }
    >     while (!feof(fpi));
    >     fclose(fpi);
    >     fclose(fpo);
    >     return 0;
    >
    >
    >
    > }- Hide quoted text -
    >
    > - Show quoted text -


    Ok my apoligies all. It looks like in the time it took me to look at
    Nick K's old code and write my own I ended up getting a couple of
    parameters backwards. Looks like a write error to me. Right? If
    anyones has any input I'd appreciate.

    B
     
    Bill Cunningham, Jun 23, 2012
    #3
  4. Bill Cunningham

    Ike Naar Guest

    On 2012-06-23, Bill Cunningham <> wrote:
    > On Jun 23, 4:31?pm, Bill Cunningham <> wrote:
    >> Ok after looking a Nick's old post again, I decided to try my own
    >> copy. It seems to fill better with my style. Now it compiles can
    >> copies fine. The thing is it hasn't been tested as to whether or not
    >> it copied actual 2048 bytes at a time. I will submit it for review...
    >>
    >> #include <stdio.h>
    >>
    >> int main()


    int main(void)

    >> {
    >> ? ? size_t nread = 0;
    >> ? ? char buf[2048];
    >> ? ? FILE *fpi, *fpo;
    >> ? ? if ((fpi = fopen("t", "rb")) == NULL)
    >> ? ? ? ? return -1;
    >> ? ? if ((fpo = fopen("z", "wb")) == NULL)
    >> ? ? ? ? return -2;
    >> ? ? do {
    >> ? ? ? ? nread = fread(buf, sizeof(buf), 1, fpi);


    The second parameter of fread specifies the size of the
    elemtents to be read, and the third parameter specifies the
    (maximal) number of them. If you're going to read bytes instead
    of 2048-byte blocks, it would be more natural to use

    nread = fread(buf, 1, sizeof buf, fpi);

    >> ? ? ? ? if (ferror(fpi))
    >> ? ? ? ? ? ? return -3;
    >> ? ? ? ? fwrite(buf, sizeof(buf), nread, fpo);


    and, to match the change in the fread arguments, here it would be

    fwrite(buf, 1, nread, fpo);

    >> ? ? ? ? if (ferror(fpo))
    >> ? ? ? ? ? ? return -4;
    >> ? ? }
    >> ? ? while (!feof(fpi));
    >> ? ? fclose(fpi);
    >> ? ? fclose(fpo);
    >> ? ? return 0;
    >>
    >>
    >>
    >> }- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    > Ok I guess there must be a short count somewhere in this code. Most of
    > it has been copied I get no errors and I must admit I'm a little
    > stumped. It's got to be in the fread fwrite system somehow.
    >
    > B



    --

    SDF Public Access UNIX System - http://sdf.lonestar.org
     
    Ike Naar, Jun 23, 2012
    #4
  5. Bill Cunningham

    John Gordon Guest

    In <> Bill Cunningham <> writes:

    > Ok my apoligies all. It looks like in the time it took me to look at
    > Nick K's old code and write my own I ended up getting a couple of
    > parameters backwards. Looks like a write error to me. Right? If
    > anyones has any input I'd appreciate.


    If the program isn't behaving the way you want, tell us that. Say
    exactly what it is doing wrong.

    Does it not compile?
    Does it run, but print an error message?
    Does it run, but not produce the desired output?

    Vague comments like "Looks like a write error" don't help us track down
    the problem.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
     
    John Gordon, Jun 24, 2012
    #5
  6. On Jun 24, 10:01 am, John Gordon <> wrote:

    > If the program isn't behaving the way you want, tell us that.  Say
    > exactly what it is doing wrong.
    >
    > Does it not compile?
    > Does it run, but print an error message?
    > Does it run, but not produce the desired output?
    >
    > Vague comments like "Looks like a write error" don't help us track down
    > the problem.


    Well It's like I said above it's a short count. diff says the files
    differ. I'm not wanting to copy 2048 bytes but 2048 byte sized blocks.
    I can copy bytes with fputs and fputc. I want a copy of the entire
    file.

    B
     
    Bill Cunningham, Jun 24, 2012
    #6
  7. Bill Cunningham <> writes:

    > On Jun 24, 10:01 am, John Gordon <> wrote:
    >
    >> If the program isn't behaving the way you want, tell us that.  Say
    >> exactly what it is doing wrong.
    >>
    >> Does it not compile?
    >> Does it run, but print an error message?
    >> Does it run, but not produce the desired output?
    >>
    >> Vague comments like "Looks like a write error" don't help us track down
    >> the problem.

    >
    > Well It's like I said above it's a short count. diff says the files
    > differ. I'm not wanting to copy 2048 bytes but 2048 byte sized blocks.
    > I can copy bytes with fputs and fputc. I want a copy of the entire
    > file.


    Did you miss the correct analysis of the bug? It was posted yesterday by
    Ike Naar.

    Another strategy would have been to compare all the changes you made
    from the original working code. That would have enabled you to find the
    bug that Ike pointed out by yourself.

    --
    Ben.
     
    Ben Bacarisse, Jun 24, 2012
    #7
  8. On Jun 24, 3:06 pm, Ben Bacarisse <> wrote:
    > Bill Cunningham <> writes:
    > > On Jun 24, 10:01 am, John Gordon <> wrote:

    >
    > >> If the program isn't behaving the way you want, tell us that.  Say
    > >> exactly what it is doing wrong.

    >
    > >> Does it not compile?
    > >> Does it run, but print an error message?
    > >> Does it run, but not produce the desired output?

    >
    > >> Vague comments like "Looks like a write error" don't help us track down
    > >> the problem.

    >
    > >  Well It's like I said above it's a short count. diff says the files
    > > differ. I'm not wanting to copy 2048 bytes but 2048 byte sized blocks.
    > > I can copy bytes with fputs and fputc. I want a copy of the entire
    > > file.

    >
    > Did you miss the correct analysis of the bug?  It was posted yesterday by
    > Ike Naar.


    Both the posts were written by me at the same time. 6:18 and 6:32 PM
    were when each were posted. Then Ike responded at 6:42. Why it took so
    long for the 2nd post to post I don't know.
    >
    > Another strategy would have been to compare all the changes you made
    > from the original working code.  That would have enabled you to find the
    > bug that Ike pointed out by yourself.
    >

    I did. My original post was premature.

    Bill
     
    Bill Cunningham, Jun 24, 2012
    #8
  9. On Jun 23, 6:42 pm, Ike Naar <> wrote:
    > On 2012-06-23, Bill Cunningham <> wrote:
    >
    > > On Jun 23, 4:31?pm, Bill Cunningham <> wrote:
    > >> Ok after looking a Nick's old post again, I decided to try my own
    > >> copy. It seems to fill better with my style. Now it compiles can
    > >> copies fine. The thing is it hasn't been tested as to whether or not
    > >> it copied actual 2048 bytes at a time. I will submit it for review...

    >
    > >> #include <stdio.h>

    >
    > >> int main()

    >
    > int main(void)
    >
    > >> {
    > >> ? ? size_t nread = 0;
    > >> ? ? char buf[2048];
    > >> ? ? FILE *fpi, *fpo;
    > >> ? ? if ((fpi = fopen("t", "rb")) == NULL)
    > >> ? ? ? ? return -1;
    > >> ? ? if ((fpo = fopen("z", "wb")) == NULL)
    > >> ? ? ? ? return -2;
    > >> ? ? do {
    > >> ? ? ? ? nread = fread(buf, sizeof(buf), 1, fpi);

    >
    > The second parameter of fread specifies the size of the
    > elemtents to be read, and the third parameter specifies the
    > (maximal) number of them. If you're going to read bytes instead
    > of 2048-byte blocks, it would be more natural to use
    >
    >         nread = fread(buf, 1, sizeof buf, fpi);
    >
    > >> ? ? ? ? if (ferror(fpi))
    > >> ? ? ? ? ? ? return -3;
    > >> ? ? ? ? fwrite(buf, sizeof(buf), nread, fpo);

    >
    > and, to match the change in the fread arguments, here it would be
    >
    >         fwrite(buf, 1, nread, fpo);
    >
    >
    >
    >
    >
    > >> ? ? ? ? if (ferror(fpo))
    > >> ? ? ? ? ? ? return -4;
    > >> ? ? }
    > >> ? ? while (!feof(fpi));
    > >> ? ? fclose(fpi);
    > >> ? ? fclose(fpo);
    > >> ? ? return 0;

    >
    > >> }- Hide quoted text -

    >
    > >> - Show quoted text -

    >
    > > Ok I guess there must be a short count somewhere in this code. Most of
    > > it has been copied I get no errors and I must admit I'm a little
    > > stumped. It's got to be in the fread fwrite system somehow.

    >
    > > B


    Thanks Ike and I hope this post was not premature. I altered my code
    some taking your advice and looking at Nick's old code. Here's what I
    have now and it compiles and runs fine and a complete file is copied.
    I think in 2048 blocks too. Here's a copy of my amended code...

    #include <stdio.h>

    int main()
    {
    size_t nread = 2048;
    char buf[2048];
    FILE *fpi, *fpo;
    if ((fpi = fopen("t", "rb")) == NULL)
    return -1;
    if ((fpo = fopen("z", "wb")) == NULL)
    return -2;
    do {
    nread = fread(buf, 1, sizeof buf, fpi);
    if (ferror(fpi))
    printf("error 3");
    fwrite(buf, 1, nread, fpo);
    if (ferror(fpo))
    printf("error 4");
    }
    while (!feof(fpi));
    fclose(fpi);
    fclose(fpo);
    return 0;
    }

    Bill
     
    Bill Cunningham, Jun 24, 2012
    #9
  10. Bill Cunningham <> writes:
    <snip>
    > Thanks Ike and I hope this post was not premature. I altered my code
    > some taking your advice and looking at Nick's old code. Here's what I
    > have now and it compiles and runs fine and a complete file is copied.
    > I think in 2048 blocks too. Here's a copy of my amended code...
    >
    > #include <stdio.h>
    >
    > int main()


    Why not int main(void)? It may not matter to you here, but it's a good
    idea to get into the habit of using the best C idioms everywhere.

    > {
    > size_t nread = 2048;


    I prefer not to initialise variables unless the value is actually
    useful.

    > char buf[2048];
    > FILE *fpi, *fpo;
    > if ((fpi = fopen("t", "rb")) == NULL)
    > return -1;
    > if ((fpo = fopen("z", "wb")) == NULL)
    > return -2;


    Are negative return values useful to you on your system? They aren't
    very useful on mine.

    A program that has hard-wired file names like this is not going to be
    useful. I know this is learning exercise, but the next step would be to
    learn how to get rid of this restriction.

    > do {
    > nread = fread(buf, 1, sizeof buf, fpi);
    > if (ferror(fpi))
    > printf("error 3");
    > fwrite(buf, 1, nread, fpo);
    > if (ferror(fpo))
    > printf("error 4");


    The error handling is inconsistent. You print a message for two errors
    and use non-zero return values for the others. It suggest you haven't
    really decided what to do with errors. Also, errors should be printed
    to stderr -- that's what it's for after all.

    > }
    > while (!feof(fpi));


    There's a bug here. What happens when there is a read error?

    > fclose(fpi);
    > fclose(fpo);


    There's a another inconsistency here. You close the streams when all
    goes well, but not when the output file can't be opened. It's a good
    idea to get into the habit of closing all open streams.

    > return 0;
    > }


    <snip>
    --
    Ben.
     
    Ben Bacarisse, Jun 24, 2012
    #10
  11. On Jun 24, 4:58 pm, Ben Bacarisse <> wrote:
    > Bill Cunningham <> writes:
    >
    > <snip>
    >
    > >  Thanks Ike and I hope this post was not premature. I altered my code
    > > some taking your advice and looking at Nick's old code. Here's what I
    > > have now and it compiles and runs fine and a complete file is copied.
    > > I think in 2048 blocks too. Here's a copy of my amended code...

    >
    > > #include <stdio.h>

    >
    > > int main()

    >
    > Why not int main(void)?  It may not matter to you here, but it's a good
    > idea to get into the habit of using the best C idioms everywhere.


    'cause no one usually uses it. () is like a synonym if I'm right.

    > > {
    > >     size_t nread = 2048;

    >
    > I prefer not to initialise variables unless the value is actually
    > useful.


    Why is it not useful in the fwrite 3rd parameter?

    > >     char buf[2048];
    > >     FILE *fpi, *fpo;
    > >     if ((fpi = fopen("t", "rb")) == NULL)
    > >    return -1;
    > >     if ((fpo = fopen("z", "wb")) == NULL)
    > >    return -2;

    >
    > Are negative return values useful to you on your system?  They aren't
    > very useful on mine.


    All negative numbers are errors. Of course I'd have to call main()
    manually get these useful. So I changed the code to print error 3 and
    error 4. But didn't completely re-write the whole code.

    > A program that has hard-wired file names like this is not going to be
    > useful.  I know this is learning exercise, but the next step would be to
    > learn how to get rid of this restriction.


    I decided not to use the infamous main(int argc,char *argv[])

    > >     do {
    > >    nread = fread(buf, 1, sizeof buf, fpi);
    > >    if (ferror(fpi))
    > >        printf("error 3");
    > >    fwrite(buf, 1, nread, fpo);
    > >    if (ferror(fpo))
    > >        printf("error 4");

    >
    > The error handling is inconsistent.  You print a message for two errors
    > and use non-zero return values for the others.  It suggest you haven't
    > really decided what to do with errors.  Also, errors should be printed
    > to stderr -- that's what it's for after all.


    Normally in code I direct to stderr. I just used printf for brevity.

    > >     }
    > >     while (!feof(fpi));

    >
    > There's a bug here.  What happens when there is a read error?


    What's exactly wrong here? Should I maybe have used
    while(ferror(fpi)&&!feof(fpi)); ?

    > >     fclose(fpi);
    > >     fclose(fpo);


    I should've written a small function like int Fclose(FILE *f1,FILE
    *f2){
    fclose(f1);
    fclose(f2);
    return 0;
    }

    So I wouldn't have to type fclose so much.

    > There's a another inconsistency here.  You close the streams when all
    > goes well, but not when the output file can't be opened.  It's a good
    > idea to get into the habit of closing all open streams.
    >
    > >     return 0;
    > > }

    >
    > <snip>
     
    Bill Cunningham, Jun 24, 2012
    #11
  12. Bill Cunningham <> writes:

    > On Jun 24, 4:58 pm, Ben Bacarisse <> wrote:
    >> Bill Cunningham <> writes:
    >>
    >> <snip>
    >>
    >> >  Thanks Ike and I hope this post was not premature. I altered my code
    >> > some taking your advice and looking at Nick's old code. Here's what I
    >> > have now and it compiles and runs fine and a complete file is copied.
    >> > I think in 2048 blocks too. Here's a copy of my amended code...

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

    >>
    >> > int main()

    >>
    >> Why not int main(void)?  It may not matter to you here, but it's a good
    >> idea to get into the habit of using the best C idioms everywhere.

    >
    > 'cause no one usually uses it. () is like a synonym if I'm right.


    It's not a synonym, but it's very similar. In C, adding void is better
    -- you usually get more help from the compiler if you write an erroneous
    call to the function.

    >> > {
    >> >     size_t nread = 2048;

    >>
    >> I prefer not to initialise variables unless the value is actually
    >> useful.

    >
    > Why is it not useful in the fwrite 3rd parameter?


    because it gets assigned before then.

    <snip>
    >> >     }
    >> >     while (!feof(fpi));

    >>
    >> There's a bug here.  What happens when there is a read error?

    >
    > What's exactly wrong here? Should I maybe have used
    > while(ferror(fpi)&&!feof(fpi)); ?


    Not quite. You need to stop when there is an error (at least when there
    is a read error) because you can't rely on eof(fpi) becomming true.

    >> >     fclose(fpi);
    >> >     fclose(fpo);

    >
    > I should've written a small function like int Fclose(FILE *f1,FILE
    > *f2){
    > fclose(f1);
    > fclose(f2);
    > return 0;
    > }
    >
    > So I wouldn't have to type fclose so much.


    That's not a very string reason to write a function.

    >> There's a another inconsistency here.  You close the streams when all
    >> goes well, but not when the output file can't be opened.  It's a good
    >> idea to get into the habit of closing all open streams.


    Is the idea of a file closing function related to this?

    >> >     return 0;
    >> > }


    --
    Ben.
     
    Ben Bacarisse, Jun 25, 2012
    #12
  13. On Jun 24, 9:15 pm, Ben Bacarisse <> wrote:

    > >> There's a bug here.  What happens when there is a read error?

    >
    > > What's exactly wrong here? Should I maybe have used
    > > while(ferror(fpi)&&!feof(fpi)); ?

    >
    > Not quite.  You need to stop when there is an error (at least when there
    > is a read error) because you can't rely on eof(fpi) becomming true.


    What could I do then? Test for ferror and do something else with
    feof ?
    > >> >     fclose(fpi);
    > >> >     fclose(fpo);

    >
    > >  I should've written a small function like int Fclose(FILE *f1,FILE
    > > *f2){
    > > fclose(f1);
    > > fclose(f2);
    > > return 0;
    > > }

    >
    > > So I wouldn't have to type fclose so much.

    >
    > That's not a very string reason to write a function.
    >
    > >> There's a another inconsistency here.  You close the streams when all
    > >> goes well, but not when the output file can't be opened.  It's a good
    > >> idea to get into the habit of closing all open streams.

    >
    > Is the idea of a file closing function related to this?
    >
    > >> >     return 0;
    > >> > }

    >
    > --
    > Ben.- Hide quoted text -
    >
    > - Show quoted text -
     
    Bill Cunningham, Jun 25, 2012
    #13
  14. Bill Cunningham <> writes:
    > On Jun 24, 9:15 pm, Ben Bacarisse <> wrote:
    >> >> There's a bug here.  What happens when there is a read error?

    >>
    >> > What's exactly wrong here? Should I maybe have used
    >> > while(ferror(fpi)&&!feof(fpi)); ?

    >>
    >> Not quite.  You need to stop when there is an error (at least when there
    >> is a read error) because you can't rely on eof(fpi) becomming true.

    >
    > What could I do then? Test for ferror and do something else with
    > feof ?


    For the benefit of other readers:

    First check the value returned by fread() or fwrite(). If that result
    indicates an error, *then* call feof() and/or ferror() to get more
    information.

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 25, 2012
    #14
  15. On Jun 23, 6:42 pm, Ike Naar <> wrote:

    [snip]

    > The second parameter of fread specifies the size of the
    > elemtents to be read, and the third parameter specifies the
    > (maximal) number of them. If you're going to read bytes instead
    > of 2048-byte blocks, it would be more natural to use
    >
    >         nread = fread(buf, 1, sizeof buf, fpi);


    [snip]

    Ok and if I wanted to read 2048 bytes blocks then would I want this
    instead?

    nread=fread(buf,sizeof buf,1,fpi);

    makes sense. Remember I'm pretty unfamilliar with these functions. I
    usually use fgetc

    Bill
     
    Bill Cunningham, Jun 26, 2012
    #15
  16. Bill Cunningham <> writes:

    > On Jun 23, 6:42 pm, Ike Naar <> wrote:
    >
    > [snip]
    >
    >> The second parameter of fread specifies the size of the
    >> elemtents to be read, and the third parameter specifies the
    >> (maximal) number of them. If you're going to read bytes instead
    >> of 2048-byte blocks, it would be more natural to use
    >>
    >>         nread = fread(buf, 1, sizeof buf, fpi);

    >
    > [snip]
    >
    > Ok and if I wanted to read 2048 bytes blocks then would I want this
    > instead?
    >
    > nread=fread(buf,sizeof buf,1,fpi);
    >
    > makes sense. Remember I'm pretty unfamilliar with these functions. I
    > usually use fgetc


    Ike's post has led you astray (not deliberately, I'm sure). Both forms
    read 2048-byte blocks when they can. The difference comes when you get
    close to the end of the file. When there are fewer than 2048 bytes left
    the first form

    nread = fread(buf, 1, sizeof buf, fpi);

    reads what it can and puts the number of bytes read in nread. You need
    that because you want to write exactly that number of bytes in the
    subsequent call to fwrite. If you use this:

    nread = fread(buf, sizeof buf, 1, fpi);

    nread will be 0 since zero 2048-byte objects were read. Now you don't
    know how much, if any, of the bytes in buf need to be written out.

    --
    Ben.
     
    Ben Bacarisse, Jun 26, 2012
    #16
  17. Bill Cunningham

    Guest

    On Monday, June 25, 2012 10:11:06 PM UTC+1, Keith Thompson wrote:
    > Bill Cunningham <> writes:
    > > On Jun 24, 9:15 pm, Ben Bacarisse <> wrote:
    > >> >> There's a bug here.  What happens when there is a read error?
    > >>
    > >> > What's exactly wrong here? Should I maybe have used
    > >> > while(ferror(fpi)&&!feof(fpi)); ?
    > >>
    > >> Not quite.  You need to stop when there is an error (at least when there
    > >> is a read error) because you can't rely on eof(fpi) becomming true.

    > >
    > > What could I do then? Test for ferror and do something else with
    > > feof ?

    >
    > For the benefit of other readers:
    >
    > First check the value returned by fread() or fwrite().

    If that result
    > indicates an error, *then* call feof() and/or ferror() to get more
    > information.



    which is what the original code did...
     
    , Jun 26, 2012
    #17
  18. writes:

    > On Monday, June 25, 2012 10:11:06 PM UTC+1, Keith Thompson wrote:
    >> Bill Cunningham <> writes:
    >> > On Jun 24, 9:15 pm, Ben Bacarisse <> wrote:
    >> >> >> There's a bug here.  What happens when there is a read error?
    >> >>
    >> >> > What's exactly wrong here? Should I maybe have used
    >> >> > while(ferror(fpi)&&!feof(fpi)); ?
    >> >>
    >> >> Not quite.  You need to stop when there is an error (at least when there
    >> >> is a read error) because you can't rely on eof(fpi) becomming true.
    >> >
    >> > What could I do then? Test for ferror and do something else with
    >> > feof ?

    >>
    >> For the benefit of other readers:
    >>
    >> First check the value returned by fread() or fwrite().

    > If that result
    >> indicates an error, *then* call feof() and/or ferror() to get more
    >> information.

    >
    > which is what the original code did...


    Yes. In fact, if anyone is using this thread to learn up on C's IO they
    should compare your original posting with Bill's latest re-write.
    As far as I can tell, every change to the code has made it slightly
    worse, so all the differences are significant.

    It's a good way to learn. I used to do something similar when teaching.
    Rather than just post a single model answer, I'd post some of the best
    student answers as well. That way it was likely that there was at least
    one good example that matched up with every reasonable approach to a
    problem.

    In that spirit, here is my "programming 101" submission. It uses quite
    a different structure and style:

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

    int main(int argc, char *argv[])
    {
    FILE *fpi = argc > 1 ? fopen(argv[1], "rb") : NULL;
    FILE *fpo = argc > 2 ? fopen(argv[2], "wb") : NULL;
    if (fpi && fpo) {
    size_t nread;
    char buf[2048];
    while ((nread = fread(buf, 1, sizeof buf, fpi)) > 0 &&
    fwrite(buf, 1, nread, fpo) == nread)
    /* do nothing */;

    int copied_ok = feof(fpi) && !ferror(fpo);
    if (fclose(fpi) + fclose(fpo) == 0 && copied_ok)
    return EXIT_SUCCESS;
    fprintf(stderr, "Error copying file.\n");
    }
    else if (fpi) {
    fclose(fpi);
    fprintf(stderr, "Unable to open output file.\n");
    }
    else if (fpo) {
    fclose(fpo);
    fprintf(stderr, "Unable to open input file.\n");
    }
    return EXIT_FAILURE;
    }

    --
    Ben.
     
    Ben Bacarisse, Jun 26, 2012
    #18
  19. On Jun 25, 10:18 pm, Ben Bacarisse <> wrote:
    > Bill Cunningham <> writes:
    > > On Jun 23, 6:42 pm, Ike Naar <> wrote:

    >
    > > [snip]

    >
    > >> The second parameter of fread specifies the size of the
    > >> elemtents to be read, and the third parameter specifies the
    > >> (maximal) number of them. If you're going to read bytes instead
    > >> of 2048-byte blocks, it would be more natural to use

    >
    > >>         nread = fread(buf, 1, sizeof buf, fpi);

    >
    > > [snip]

    >
    > > Ok and if I wanted to read 2048 bytes blocks then would I want this
    > > instead?

    >
    > > nread=fread(buf,sizeof buf,1,fpi);

    >
    > > makes sense. Remember I'm pretty unfamilliar with these functions. I
    > > usually use fgetc

    >
    > Ike's post has led you astray (not deliberately, I'm sure).  Both forms
    > read 2048-byte blocks when they can.  The difference comes when you get
    > close to the end of the file.  When there are fewer than 2048 bytes left
    > the first form
    >
    >   nread = fread(buf, 1, sizeof buf, fpi);
    >
    > reads what it can and puts the number of bytes read in nread.  You need
    > that because you want to write exactly that number of bytes in the
    > subsequent call to fwrite.  If you use this:
    >
    >   nread = fread(buf, sizeof buf, 1, fpi);
    >
    > nread will be 0 since zero 2048-byte objects were read.  Now you don't
    > know how much, if any, of the bytes in buf need to be written out.


    Ok. I am slowly coming around to this. Would it be a good idea while
    trying to grasp this to forget ferror and feof? Are they really
    needed? I have copied your latest code. It's alittle beyond my reading
    abillity since there is so much shorthand. And your rewrite of Nick's
    original code my compiler said hand a couple of errors. ) expected
    before { or something trivial like that. I just in my code didn't use
    a command line interface with main(int argc,char **argv).

    Bill
     
    Bill Cunningham, Jun 26, 2012
    #19
    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. Brady

    problem using fread, fwrite, and fsetpos

    Brady, Jul 17, 2003, in forum: C Programming
    Replies:
    8
    Views:
    983
    Dave Thompson
    Jul 21, 2003
  2. Guest

    fread / fwrite error

    Guest, Aug 1, 2003, in forum: C Programming
    Replies:
    9
    Views:
    1,097
    Emmanuel Delahaye
    Aug 7, 2003
  3. CBFalconer

    Re: fread/fwrite Bits

    CBFalconer, Jan 3, 2004, in forum: C Programming
    Replies:
    0
    Views:
    876
    CBFalconer
    Jan 3, 2004
  4. mazsx
    Replies:
    2
    Views:
    898
    Toni Uusitalo
    Nov 11, 2005
  5. fread fwrite struct

    , Mar 30, 2006, in forum: C Programming
    Replies:
    4
    Views:
    512
    Michael Mair
    Mar 31, 2006
Loading...

Share This Page