question

B

Barry Schwarz

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.

If your input file was exactly 512 bytes long, then it probably
contained 128 integers, not 512. There are very few home systems
where sizeof(int) is 1. On your system, sizeof(int) is apparently 4
and 512 int will require 2048 bytes.

You forgot to check the return from fread which would have told you
exactly how many int had been read (which you would then use as the
third argument to fwrite). Your code as written says:
Read up to 512 int
Regardless of how many were read, write 512 to the output.

If you really meant to process bytes, change buf to a char array and
change the second argument of both fread and fwrite to sizeof *buf.


Remove del for email
 
B

Bill Cunningham

Kenneth Brody said:
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?

char on my system is 8 bit. I guess I could've used it instead of int
which is 32 bit.
Why are you writing 512 of these, regardless of how many were read?

Why are you discarding the return from fread()?
I'm not quite sure what you mean here.
 
D

Default User

Bill said:
char on my system is 8 bit. I guess I could've used it instead of
int which is 32 bit.

No "could" about it. You should have. What was your reason for int?
I'm not quite sure what you mean here.


fread() returns a value. You did not capture or examine this value.
That value is there for a reason, that reason being to tell you how
many items were successfully read.

I again STRONGLY urge you to thoroughly read up on every function you
to try to use. You use many of them incorrectly or haphazardly. This
makes your programs incorrect and/or unsafe.





Brian
 
B

Bill Cunningham

fread() returns a value. You did not capture or examine this value.
That value is there for a reason, that reason being to tell you how
many items were successfully read.

I again STRONGLY urge you to thoroughly read up on every function you
to try to use. You use many of them incorrectly or haphazardly. This
makes your programs incorrect and/or unsafe.

I get most of my info from these two places the tutorial is the best. I
can't read the standard functions prototype and return values so the second
site really doesn't help me much.
http://www.eskimo.com/~scs/cclass/
http://www-ccs.ucsd.edu/c/

I guess I can break out the old k&r2.

Bill
 
K

Kenneth Brody

Bill said:
Kenneth Brody said:
Bill Cunningham wrote: [...]
int buf[512]; [...]
fread(buf,sizeof(int),512,fp); [...]
fwrite(buf,sizeof(int),512,fp);
[...]
Why are you reading int-sized chunks when you say you want bytes?

char on my system is 8 bit. I guess I could've used it instead of int
which is 32 bit.
Why are you writing 512 of these, regardless of how many were read?

Why are you discarding the return from fread()?
I'm not quite sure what you mean here.

fread() gives a return value -- the number of items read, or zero
if an error occurred. You discard this return value, and always
call fwrite() telling it write 512 int-sized chunks, regardless of
how many were actually read.

Your code could have still "worked", had you used the return value
from fread() as the third parameter to fwrite(). I say "worked" in
quotes because of the limited scope of this program. Given your
particular system and input file, fread() would say that it read
128 int-sized chunks (512 bytes), and passing that 128 back into
fwrite() would have caused those same 512 bytes to have been
written. In fact, it would "work" as long as the input file was
an exact multiple of sizeof(int) bytes, and no longer than 512
times that size.

Of course, the correct way, given that you simply want to copy a
sequence of bytes, is to use "char" instead of "int".

--
+-------------------------+--------------------+-----------------------+
| 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]>
 
D

Default User

Bill said:
I get most of my info from these two places the tutorial is the
best. I can't read the standard functions prototype and return values
so the second site really doesn't help me much.

Tutorials are fine, but they are no substitute for a reference book. If
you have to have something online, this isn't too bad, although sparser
than I'd prefer (usage examples would help).

<http://www.cppreference.com/all_c_functions.html>

Example:

fread
Syntax:

#include <stdio.h>
int fread( void *buffer, size_t size, size_t num, FILE *stream );

The function fread() reads num number of objects (where each object is
size bytes) and places them into the array pointed to by buffer. The
data comes from the given input stream. The return value of the
function is the number of things read. You can use feof() or ferror()
to figure out if an error occurs.

I guess I can break out the old k&r2.

You should probably have that at hand.




Brian
 
M

Mark McIntyre

Bill said:
char on my system is 8 bit. I guess I could've used it instead of int
which is 32 bit.

If you want 512 lots of 8-bit objects, ask for that. Dont' tell the
compiler to read 512 lots of some other size.
I'm not quite sure what you mean here.

fread returns a value. The value is an error status. Do not ignore error
statuses.
 
B

Bill Cunningham

fread
Syntax:

#include <stdio.h>
int fread( void *buffer, size_t size, size_t num, FILE *stream );

The function fread() reads num number of objects (where each object is
size bytes) and places them into the array pointed to by buffer. The
data comes from the given input stream. The return value of the
function is the number of things read. You can use feof() or ferror()
to figure out if an error occurs.



You should probably have that at hand.

I see that the f* family of functions don't mean file. That is confusing
for a beginner. I under printf and now fprintf but I've never used vprintf.
I suppose it can be redirected to stdin, stdout, and stderr too right? I've
never used it.

Bill
 
E

Eric Sosman

Bill said:
I see that the f* family of functions don't mean file. That is confusing
for a beginner. I under printf and now fprintf but I've never used vprintf.
I suppose it can be redirected to stdin, stdout, and stderr too right? I've
never used it.

Interpreting the initial 'f' as "file" or "FILE*" seems reasonable
to me; I don't understand why you find it confusing.

vprintf() writes to stdout, and cannot be redirected anywhere else.
vfprintf() can write to any open output stream, including stdout and
stderr. It is most unusual to find anything that writes to stdin.
 
B

Bill Cunningham

vprintf() writes to stdout, and cannot be redirected anywhere else.
vfprintf() can write to any open output stream, including stdout and
stderr. It is most unusual to find anything that writes to stdin.
fgets writes to stdin maybe that's what I'm thinking of. I know advice was
given to me not to consider the functions begining with f to associated with
the FILE struct or text or binary files. Is vprintf like printf? If so why
use it? If vfprintf is like fprintf what is the purpose of the v family of
functions?

Cheers
Bill
 
E

Eric Sosman

Bill said:
fgets writes to stdin maybe that's what I'm thinking of.

Most people would say that it "reads from" stdin ...
I know advice was
given to me not to consider the functions begining with f to associated with
the FILE struct or text or binary files.

There are certainly some f-functions that have nothing to
do with FILE* streams -- fabs() and free(), for example -- so
the initial f is not a sure-fire indicator of file-ness. Maybe
that's what your advisor meant.

On the other hand, most (not all) functions that deal with
FILE* streams have an f somewhere near the start of the name.
Is vprintf like printf? If so why
use it? If vfprintf is like fprintf what is the purpose of the v family of
functions?

Personally I haven't found vprintf() useful; I suspect it's
only there for completeness' sake. It is "like" plain printf()
in that it converts argument values according to a format and sends
them to stdout, but it is different in the way it obtains those
arguments. For ordinary printf() you list the arguments right
there in the call:

printf ("This %s is %s!\n", stuffInTheBowl,
temperature > 90 ? "too hot"
: temperature < 50 ? "too cold"
: "just right");

But now suppose you want to write a function goldilocksSays()
that looks a lot like printf() and is able to do all the same
kinds of formatting, but does a little extra stuff of its own.
So you begin

void goldilocksSays(const char *format, ...) {
printf ("\"");
printf (format, ...); /* need help here */
printf ("\" said Goldilocks.\n");
}

The problem is with that printf() call in the middle: How can
you "pass along" the arguments that the caller provided to
goldilocksSays()? That's where vprintf() comes in: It does the
same thing as printf(), but uses a va_list to encapsulate those
arguments:

void goldilocksSays(const char *format, ...) {
va_list ap;
printf ("\"");

/* here comes the magic: */
va_start (ap, format); /* package the ... arguments */
vprintf(format, ap); /* print them */
va_end (ap); /* dispose of the package */

printf ("\" said Goldilocks.\n");
}

We don't need to know how many or what kinds of arguments the
caller provided for the "..." part of the parameter list, but
through the va_list mechanism we can pass them along anyhow.
And vprintf() -- and vfprintf() and vsprintf() and some of their
younger siblings -- know how to pluck the arguments from the
va_list goldilocksSays() provides, rather than from their own
"..." arguments (which they don't have).

And this, my friend, is why you need a tutorial. A tutorial
first, and a reference eventually if you get serious.
 
D

Default User

Bill said:
fgets writes to stdin maybe that's what I'm thinking of.

You meant "reads from stdin". You can't write to stdin, that's why it
has "in" in its name.

fgets() reads from a text stream opened for reading. stdin is a text
stream open for reading. It is not the only text stream that you can
read from.
I know
advice was given to me not to consider the functions begining with f
to associated with the FILE struct or text or binary files.

Most of the f* functions are indeed for operations on open file
streams. These streams may not be a file on a disk, of course. One of
the parameters will be a FILE*.

There are a few that aren't, like fabs(), floor(), and free(). These
shouldn't be too confusing though.
Is
vprintf like printf? If so why use it? If vfprintf is like fprintf
what is the purpose of the v family of functions?

I gave you a link to a page with information about functions. Did you
look up the v* ones? You'll see that that they are different.

You need to stop guessing. Look things up until you are familiar with
them. Again, I'll tell you that anything else is a waste of your time
and ours.




Brian
 
A

Antoninus Twink

You meant "reads from stdin". You can't write to stdin, that's why it
has "in" in its name.

fgets() reads from a text stream opened for reading. stdin is a text
stream open for reading. It is not the only text stream that you can
read from.


Most of the f* functions are indeed for operations on open file
streams. These streams may not be a file on a disk, of course. One of
the parameters will be a FILE*.

There are a few that aren't, like fabs(), floor(), and free(). These
shouldn't be too confusing though.

ROFL! The Loser seems to have been shamed into making a post with a
token amount of actual content - not a bad day's work for a humble
troll!
 
K

Keith Thompson

Default User said:
Tutorials are fine, but they are no substitute for a reference book.
[...]

And vice versa.

I wouldn't want to use a language without having some sort of
reference work handy, but I wouldn't want to learn one just from a
reference book. (Ok, I might, but I'm odd that way.)
 

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,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top