question

B

Bill Cunningham

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.
 
J

J. J. Farrell

Bill said:
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?
 
B

Bill Cunningham

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
 
K

Keith Thompson

Bill Cunningham said:
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 said:
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.
 
D

Default User

Bill said:
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
 
S

Serve Lau

Keith Thompson said:
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?
 
V

vippstar

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.
 
M

Mark McIntyre

Serve said:
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.

....
 
B

Bill Cunningham

Default User said:
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
 
B

Bill Cunningham

Keith Thompson said:
Bill Cunningham said:
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 said:
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.
Above, you printed an error message and terminated the program. Here
you print an error message and continue.


No error checking.


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.


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
 
B

Bill Cunningham

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?
 
S

Serve Lau

Bill Cunningham said:
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!
 
B

Bill Cunningham

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
 
J

James Kuyper

Bill said:
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.
 
K

Kenny McCormack

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.
 
J

J. J. Farrell

Serve said:
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.
 
P

Philip Potter

Bill said:
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
 
K

Kenneth Brody

Bill said:
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:[email protected]>
 
K

Kenneth Brody

Serve said:
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:[email protected]>
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

URGENT 1
error 28
Help with EXT3 Filesystem work 1
file bug 28
fread/fwrite 2 18
code 34
fseek 17
Writing a structure into a file 3

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top