question

Discussion in 'C Programming' started by Bill Cunningham, Jan 13, 2008.

  1. I wrote this small program to read a 512 block of binary data and write
    the same to a file. My code compiled well. The only thing is when I ran the
    compilers binary instead of a data file of 512 bytes I got one of 2048
    bytes.

    #include <stdio.h>

    main(){
    int buf[512];
    FILE *fp;
    fp=fopen("r.dsk","rb");
    if (fp==NULL) {printf("Error"); exit(0);}
    fread(buf,sizeof(int),512,fp);
    fclose(fp);
    fp=fopen("dat","wb");
    if (fp==NULL) {printf("Error");}
    fwrite(buf,sizeof(int),512,fp);
    fclose(fp);}

    Is it the code or some overhead from the compiler or linker?

    Bill
    The unix dd command copies exactly 512 bytes of I asked it too.
     
    Bill Cunningham, Jan 13, 2008
    #1
    1. Advertising

  2. Bill Cunningham wrote:
    > I wrote this small program to read a 512 block of binary data and write
    > the same to a file. My code compiled well. The only thing is when I ran the
    > compilers binary instead of a data file of 512 bytes I got one of 2048
    > bytes.
    >
    > #include <stdio.h>
    >
    > main(){
    > int buf[512];
    > FILE *fp;
    > fp=fopen("r.dsk","rb");
    > if (fp==NULL) {printf("Error"); exit(0);}
    > fread(buf,sizeof(int),512,fp);
    > fclose(fp);
    > fp=fopen("dat","wb");
    > if (fp==NULL) {printf("Error");}
    > fwrite(buf,sizeof(int),512,fp);
    > fclose(fp);}
    >
    > Is it the code or some overhead from the compiler or linker?


    Your code clearly writes data of the same length as 512 ints. How many
    bytes are there in an int in this implementation?
     
    J. J. Farrell, Jan 13, 2008
    #2
    1. Advertising


  3. > Your code clearly writes data of the same length as 512 ints. How many
    > bytes are there in an int in this implementation?


    Not sure. HOw would I find out like this maybe?

    printf(sizeof(int));
    puts(sizeof(int));

    Would these work? I guess I could try these. Maybe the OS calls a bock size
    2048 bytes.

    Bill
     
    Bill Cunningham, Jan 13, 2008
    #3
  4. "Bill Cunningham" <> writes:
    > I wrote this small program to read a 512 block of binary data and write
    > the same to a file. My code compiled well. The only thing is when I ran the
    > compilers binary instead of a data file of 512 bytes I got one of 2048
    > bytes.
    >
    > #include <stdio.h>
    >
    > main(){


    "int main(void) {"

    > int buf[512];
    > FILE *fp;
    > fp=fopen("r.dsk","rb");
    > if (fp==NULL) {printf("Error"); exit(0);}


    You need "#include <stdlib.h>" for exit.

    > fread(buf,sizeof(int),512,fp);


    No error checking.

    > fclose(fp);


    No error checking (yes, fclose can fail).

    > fp=fopen("dat","wb");
    > if (fp==NULL) {printf("Error");}


    Above, you printed an error message and terminated the program. Here
    you print an error message and continue.

    > fwrite(buf,sizeof(int),512,fp);


    No error checking.

    > fclose(fp);}


    No error checking (yes, fclose can fail).

    Add "return 0;".

    *Please* put the closing "}" on a line by itself. It's very difficult
    to see.

    > Is it the code or some overhead from the compiler or linker?


    And finally, the answer to your question:

    The program is doing exactly what it's supposed to do. Read the
    documentation for fread() and fwrite(). They both take two size_t
    arguments, the size in bytes of each element and the number of
    elements. You're asking fread() to read 512 element, each of which is
    sizeof(int) bytes (in other words, 512 ints, not 512 bytes). If int
    is 4 bytes on your system, you'll read and write 2048 bytes (assuming
    there are no errors).

    One more thing: it's conventional to print error messages to stderr,
    and to use the argument to exit() to indicate success or failure.
    Rather than

    if (fp==NULL) {printf("Error"); exit(0);}

    I'd write:

    if (fp == NULL) {
    fprintf(stderr, "Error\n");
    exit(EXIT_FAILURE);
    }

    Yes, I also changed the code layout. Whitespace is not in short
    supply; use as much as you need to make the code clear and readable.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 13, 2008
    #4
  5. Bill Cunningham

    Default User Guest

    Bill Cunningham wrote:

    >
    > > Your code clearly writes data of the same length as 512 ints. How
    > > many bytes are there in an int in this implementation?

    >
    > Not sure. HOw would I find out like this maybe?
    >
    > printf(sizeof(int));
    > puts(sizeof(int));
    >
    > Would these work? I guess I could try these. Maybe the OS calls a
    > bock size 2048 bytes.


    Come on man. Look stuff up. I told you before, you're wasting our time
    and yours.



    Brian
     
    Default User, Jan 13, 2008
    #5
  6. Bill Cunningham

    Serve Lau Guest

    "Keith Thompson" <> schreef in bericht
    news:...
    >> fclose(fp);}

    >
    > No error checking (yes, fclose can fail).


    > Yes, I also changed the code layout. Whitespace is not in short
    > supply; use as much as you need to make the code clear and readable.


    I'm wondering how to handle failure of fclose. Has anyone ever had it fail
    and for what reasons?
     
    Serve Lau, Jan 13, 2008
    #6
  7. Bill Cunningham

    Guest

    On Jan 13, 11:50 am, "Serve Lau" <> wrote:
    > "Keith Thompson" <> schreef in berichtnews:...
    >
    > >> fclose(fp);}

    >
    > > No error checking (yes, fclose can fail).
    > > Yes, I also changed the code layout. Whitespace is not in short
    > > supply; use as much as you need to make the code clear and readable.

    >
    > I'm wondering how to handle failure of fclose. Has anyone ever had it fail
    > and for what reasons?


    example snip (without headers/initialization)
    --
    fwrite(buf, 1, strlen(buf), fptr);
    if(ferror(fptr)) {
    /* handle appropriatelly */
    }
    fclose(fptr);
    --
    In that example, fclose might fail because the data written by the
    fwrite call is still contained in a buffer provided by the stream
    fptr. When fclose is called, it is first necessary to force the
    unwritten data in the buffer out to the disk/device before closing the
    stream.
    If the disk is full (or for some other reason the data cannot be
    written) fclose fails.
     
    , Jan 13, 2008
    #7
  8. Serve Lau wrote:
    >
    > "Keith Thompson" <> schreef in bericht
    > news:...
    >>> fclose(fp);}

    >>
    >> No error checking (yes, fclose can fail).

    >
    >> Yes, I also changed the code layout. Whitespace is not in short
    >> supply; use as much as you need to make the code clear and readable.

    >
    > I'm wondering how to handle failure of fclose.


    fprintf(stderr, "Unable to close file, data may have been lost - disk
    full or removed?");

    > Has anyone ever had it
    > fail and for what reasons?


    Example: Open file on floppy disk, eject floppy.
    Example: open file on network server, cut network cable.

    ....

    --
    Mark McIntyre

    CLC FAQ <http://c-faq.com/>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
     
    Mark McIntyre, Jan 13, 2008
    #8
  9. "Default User" <> wrote in message
    news:...
    > Bill Cunningham wrote:
    >
    >>
    >> > Your code clearly writes data of the same length as 512 ints. How
    >> > many bytes are there in an int in this implementation?

    >>
    >> Not sure. HOw would I find out like this maybe?
    >>
    >> printf(sizeof(int));
    >> puts(sizeof(int));
    >>
    >> Would these work? I guess I could try these. Maybe the OS calls a
    >> bock size 2048 bytes.

    >
    > Come on man. Look stuff up. I told you before, you're wasting our time
    > and yours.
    >
    >
    >
    > Brian


    Oh I got it I remember "The first argument printf wants is a string"

    Bill
     
    Bill Cunningham, Jan 13, 2008
    #9
  10. "Keith Thompson" <> wrote in message
    news:...
    > "Bill Cunningham" <> writes:
    >> I wrote this small program to read a 512 block of binary data and
    >> write
    >> the same to a file. My code compiled well. The only thing is when I ran
    >> the
    >> compilers binary instead of a data file of 512 bytes I got one of 2048
    >> bytes.
    >>
    >> #include <stdio.h>
    >>
    >> main(){

    >
    > "int main(void) {"
    >
    >> int buf[512];
    >> FILE *fp;
    >> fp=fopen("r.dsk","rb");
    >> if (fp==NULL) {printf("Error"); exit(0);}

    >
    > You need "#include <stdlib.h>" for exit.
    >
    >> fread(buf,sizeof(int),512,fp);

    >
    > No error checking.
    >
    >> fclose(fp);

    >
    > No error checking (yes, fclose can fail).


    I don't remember reading that in my lliterature. Thanks for the tip.

    >> fp=fopen("dat","wb");
    >> if (fp==NULL) {printf("Error");}

    >
    > Above, you printed an error message and terminated the program. Here
    > you print an error message and continue.
    >
    >> fwrite(buf,sizeof(int),512,fp);

    >
    > No error checking.
    >
    >> fclose(fp);}

    >
    > No error checking (yes, fclose can fail).
    >
    > Add "return 0;".
    >
    > *Please* put the closing "}" on a line by itself. It's very difficult
    > to see.
    >
    >> Is it the code or some overhead from the compiler or linker?

    >
    > And finally, the answer to your question:
    >
    > The program is doing exactly what it's supposed to do. Read the
    > documentation for fread() and fwrite(). They both take two size_t
    > arguments, the size in bytes of each element and the number of
    > elements. You're asking fread() to read 512 element, each of which is
    > sizeof(int) bytes (in other words, 512 ints, not 512 bytes). If int
    > is 4 bytes on your system, you'll read and write 2048 bytes (assuming
    > there are no errors).
    >
    > One more thing: it's conventional to print error messages to stderr,
    > and to use the argument to exit() to indicate success or failure.
    > Rather than
    >
    > if (fp==NULL) {printf("Error"); exit(0);}
    >
    > I'd write:
    >
    > if (fp == NULL) {
    > fprintf(stderr, "Error\n");
    > exit(EXIT_FAILURE);
    > }


    Okay. stderr. I skipped ahead in the tutorial to write this. But I'm
    actually learning C! If I could get as good at as I am Basic I'll be like
    Richard Heathfield or Ben Pfaff. Maybe even dmr. It's great to have a
    community.

    > Yes, I also changed the code layout. Whitespace is not in short
    > supply; use as much as you need to make the code clear and readable.


    This is a question of style. That I'll have to learn. All my code so far
    is snippets. I'll have to catch up on that :)

    Bill
     
    Bill Cunningham, Jan 13, 2008
    #10

  11. > One more thing: it's conventional to print error messages to stderr,
    > and to use the argument to exit() to indicate success or failure.
    > Rather than
    >
    > if (fp==NULL) {printf("Error"); exit(0);}
    >
    > I'd write:
    >
    > if (fp == NULL) {
    > fprintf(stderr, "Error\n");
    > exit(EXIT_FAILURE);
    > }


    Why fprintf ? Why not printf ? Especially if you are writing in binary
    mode?

    > Yes, I also changed the code layout. Whitespace is not in short
    > supply; use as much as you need to make the code clear and readable.
    >
     
    Bill Cunningham, Jan 13, 2008
    #11
  12. Bill Cunningham

    Serve Lau Guest

    "Bill Cunningham" <> schreef in bericht
    news:Rxrij.4314$Zo3.2910@trnddc02...
    > Okay. stderr. I skipped ahead in the tutorial to write this. But I'm
    > actually learning C! If I could get as good at as I am Basic I'll be like
    > Richard Heathfield or Ben Pfaff. Maybe even dmr. It's great to have a
    > community.


    arw Cuddly Keith to whom you replied also knows his way around the language!
     
    Serve Lau, Jan 13, 2008
    #12

  13. > Your code clearly writes data of the same length as 512 ints. How many
    > bytes are there in an int in this implementation?


    I checked with sizeof. Chars are 8 bit and ints are 32 bit in this OS. I
    actually have a 64 bit address bus but the OS I'm using, linux is a 32 bit
    OS.

    Bill
     
    Bill Cunningham, Jan 13, 2008
    #13
  14. Bill Cunningham

    James Kuyper Guest

    Bill Cunningham wrote:
    >> One more thing: it's conventional to print error messages to stderr,
    >> and to use the argument to exit() to indicate success or failure.
    >> Rather than
    >>
    >> if (fp==NULL) {printf("Error"); exit(0);}
    >>
    >> I'd write:
    >>
    >> if (fp == NULL) {
    >> fprintf(stderr, "Error\n");
    >> exit(EXIT_FAILURE);
    >> }

    >
    > Why fprintf ? Why not printf ? ...


    Because printf() always sends it's output to stdout, while fprintf() can
    send it's output anywhere you specify, including in particular stderr,
    which is the appropriate destination for error message. It's commonplace
    for stdout to be redirected into a file, in which case the message won't
    be noticed until a human actually reads the file. It's also common for
    the standard output of one problem to be piped into the standard input
    of another program. If that second program isn't written to recognize
    and correctly handle the error message, all kinds of weird things can
    happen; the resulting error messages are likely to be far less
    informative than the original message.

    Of course, all of this is most relevant when running programs from the
    command line, which is the way most of my programs are used. If, like
    many programmers, you're writing code for a GUI program, both stdout and
    stderr are inappropriate. You'll want to create a pop-up message window
    of some kind - the details are highly platform-specific, and outside the
    scope of the C standard.
     
    James Kuyper, Jan 13, 2008
    #14
  15. In article <8f657$478a6bb4$541fc2ec$1.nb.home.nl>,
    Serve Lau <> wrote:
    >
    >"Bill Cunningham" <> schreef in bericht
    >news:Rxrij.4314$Zo3.2910@trnddc02...
    >> Okay. stderr. I skipped ahead in the tutorial to write this. But I'm
    >> actually learning C! If I could get as good at as I am Basic I'll be like
    >> Richard Heathfield or Ben Pfaff. Maybe even dmr. It's great to have a
    >> community.

    >
    >arw Cuddly Keith to whom you replied also knows his way around the language!


    I think that was the point being made. Keith, despite being my nominee
    for the most stuck-up/humorless individual to have ever walked the face
    of this earth, is basically a sensible person, and not a total twit like
    the two turds mentioned (clearly in jest) above.
     
    Kenny McCormack, Jan 13, 2008
    #15
  16. Bill Cunningham

    Default User Guest

    Bill Cunningham wrote:

    >
    > > One more thing: it's conventional to print error messages to stderr,
    > > and to use the argument to exit() to indicate success or failure.
    > > Rather than
    > >
    > > if (fp==NULL) {printf("Error"); exit(0);}
    > >
    > > I'd write:
    > >
    > > if (fp == NULL) {
    > > fprintf(stderr, "Error\n");
    > > exit(EXIT_FAILURE);
    > > }

    >
    > Why fprintf ? Why not printf ? Especially if you are writing in
    > binary mode?


    Error messages should by written to stderr.




    Brian
     
    Default User, Jan 13, 2008
    #16
  17. Serve Lau wrote:
    >
    > "Keith Thompson" <> schreef in bericht
    > news:...
    >>> fclose(fp);}

    >>
    >> No error checking (yes, fclose can fail).

    >
    >> Yes, I also changed the code layout. Whitespace is not in short
    >> supply; use as much as you need to make the code clear and readable.

    >
    > I'm wondering how to handle failure of fclose. Has anyone ever had it
    > fail and for what reasons?


    Remember that you're dealing with buffered streams. Success from
    fwrite() might mean no more than success in transferring the data to a
    buffer in memory. The fclose() call is what triggers the cleaning up of
    the stream and the sending of the data to its destination. If you have
    written to a file and the subsequent fclose() fails, you'd be wise to
    treat it as a write failure.
     
    J. J. Farrell, Jan 14, 2008
    #17
  18. Bill Cunningham wrote:
    >> One more thing: it's conventional to print error messages to stderr,
    >> and to use the argument to exit() to indicate success or failure.
    >> Rather than
    >>
    >> if (fp==NULL) {printf("Error"); exit(0);}
    >>
    >> I'd write:
    >>
    >> if (fp == NULL) {
    >> fprintf(stderr, "Error\n");
    >> exit(EXIT_FAILURE);
    >> }

    >
    > Why fprintf ? Why not printf ? Especially if you are writing in binary
    > mode?


    Who said anything about binary mode?

    I believe you are confused about fprintf() and think the 'f' stands for
    "file". While this is a reasonable interpretation, fprintf() actually is
    more general and outputs to streams, of which files are only a subset.
    Other possible streams include outputting to the screen or a printer, or
    sending data over the network.

    This confusion is compounded by the fact that in C, streams are
    represented using the type FILE - a terrible name in hindsight.

    There are three (I think) standard predefined streams: stdin, stdout,
    and stderr. stdin is an input stream, while stdout and stderr are both
    output streams. The reason there are two is that it makes sense to
    separate "regular" output from errors.

    This makes most sense on unix: If I type
    user@host~$ grep *.c myfunc >myfunc-usage.txt
    then I have instructed 'grep' to send all its output to the file
    'myfunc-usage.txt'; this is achieved by changing stdout to refer to this
    file. If grep encounters an error, however, I don't want it to write the
    error message to 'myfunc-usage.txt', I want it to show the error on the
    screen. grep can do this by writing to stderr.

    Phil
     
    Philip Potter, Jan 14, 2008
    #18
  19. Bill Cunningham wrote:
    >
    > I wrote this small program to read a 512 block of binary data and write
    > the same to a file. My code compiled well. The only thing is when I ran the
    > compilers binary instead of a data file of 512 bytes I got one of 2048
    > bytes.
    >
    > #include <stdio.h>
    >
    > main(){
    > int buf[512];


    Why "int"?

    > FILE *fp;
    > fp=fopen("r.dsk","rb");
    > if (fp==NULL) {printf("Error"); exit(0);}
    > fread(buf,sizeof(int),512,fp);


    Here, you read up to 512 int-sized values, and discard the return
    value, so you don't know how many were actually read.

    > fclose(fp);
    > fp=fopen("dat","wb");
    > if (fp==NULL) {printf("Error");}


    You should do something about the failure, besides simply say
    "Error" and then fwrite() to the NULL stream.

    > fwrite(buf,sizeof(int),512,fp);


    Here, you unconditionally write 512 int-sized values, regardless
    of how many were read.

    > fclose(fp);}
    >
    > Is it the code or some overhead from the compiler or linker?


    It's your code. If sizeof(int)==4, then the program did exactly
    what you told it to do.

    > The unix dd command copies exactly 512 bytes of I asked it too.


    That's because you told "dd" to copy 512 bytes, not 512 int-sized
    values.

    Why are you reading int-sized chunks when you say you want bytes?

    Why are you writing 512 of these, regardless of how many were read?

    Why are you discarding the return from fread()?

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Jan 15, 2008
    #19
  20. Serve Lau wrote:
    >
    > "Keith Thompson" <> schreef in bericht
    > news:...
    > >> fclose(fp);}

    > >
    > > No error checking (yes, fclose can fail).

    >
    > > Yes, I also changed the code layout. Whitespace is not in short
    > > supply; use as much as you need to make the code clear and readable.

    >
    > I'm wondering how to handle failure of fclose. Has anyone ever had it fail
    > and for what reasons?


    Consider an output stream which is buffered, and the buffered data,
    once written, will cause the file to grow, and the filesystem on which
    the file resides is currently full.

    You now call fclose() on that stream.

    Without knowing how your implementation handles an fwrite()/fflush()
    failure within fclose(), I can't say whether fclose() will fail, or
    ignore the internal failure. However, it's certainly possible that
    the fwrite()/fflush() failure will cause fclose() to fail.

    Now, as to how to handle it? That's another issue entirely.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Jan 15, 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. sean
    Replies:
    1
    Views:
    620
    Cowboy \(Gregory A. Beamer\)
    Oct 20, 2003
  2. =?Utf-8?B?UnlhbiBTbWl0aA==?=

    Quick Question - Newby Question

    =?Utf-8?B?UnlhbiBTbWl0aA==?=, Feb 14, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    691
    Iain Norman
    Feb 16, 2005
  3. =?Utf-8?B?YW5kcmV3MDA3?=

    question row filter (more of sql query question)

    =?Utf-8?B?YW5kcmV3MDA3?=, Oct 5, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    968
    Scott Allen
    Oct 6, 2005
  4. Philip Meyer
    Replies:
    0
    Views:
    442
    Philip Meyer
    Nov 30, 2003
  5. Bit Byte
    Replies:
    1
    Views:
    875
    Teemu Keiski
    Jan 28, 2007
Loading...

Share This Page