On Fri, 14 Sep 2012 17:29:00 -0400, "Bill Cunningham"
snip unrelated quotes from previous messages
#include <stdio.h>
struct param {
char *infile;
char *outfile;
void *buf;
};
#include "p.h"
int copi(struct param p)
{
size_t nread, nwrite;
FILE *in, *out;
if ((in = fopen(p.infile, "rb")) == NULL) {
perror("fopen 1");
return 1;
}
if ((out = fopen(p.outfile, "wb")) == NULL) {
perror("fopen 2");
return 2;
}
do {
nread = fread(p.buf, 1, sizeof p.buf, in);
p.buf is a pointer, not an array. This code will cause the input data
to be placed in the memory where p.buf points to. Unfortunately, it
will read only sizeof(void*) bytes (usually 4 or 8). Your third
argument should evaluate to the size of the area that p.buf points to.
nwrite = fwrite(p.buf, 1, nread, out);
At some point, you should confirm that fread was successful. Depending
on where the out stream resides, checking fwrite may also make sense.
This loop will never end if there is an error reading from in.
fclose(in);
fclose(out);
printf("%zu %zu\n", nread, nwrite);
Of what significance is the amount of data processed by the last read
and write? Why do you print only the results of the last iteration
through the while loop?
return 0;
}
My question concerns the generic pointer in the struct. It's the prototype
for fread/fwrite in my copi function but what if I wanted a int * or char *
You should not have, and you didn't show, a prototype for fread or
fwrite in your function. The prototype should always be obtained by
including the stdio.h standard header.
how would I choose that in a file calling main? Say I want buf to be a
What do you mean when you say a file is "calling main"? Only a
function can call a function. The only exception is the initial call
to main which is performed by the startup code.
One more time - no matter what type of object pointer you code as the
first argument in your call to fread, fread WILL ALWAYS RECEIVE A
void*. When fread transfers the data to your buffer, it takes no
notice of the type of data. It doesn't know and doesn't care about
types. It is simply transferring bytes. The same is true for fwrite.
If you attempt to access the data with something other than fwrite,
then the type becomes important. Go back and read my comments on this
in my 9/13 11:26PM post.
If you have an array x (of any type such as int or char), then in the
calling program you can simply assign the address of the array to
p.buf with the statement
p.buf = x;
Then when you call fread, the data will be placed in the array. IT IS
YOUR JOB to insure that the array x is the correct type for the data
that is in the file. You do not need a separate int* or char*.
Make up your mind. Do you want buf to be an object that holds the
data being read or a pointer to an area that will hold the data? Right
now, buf is a pointer and can point to any object you would like. If
you want buf to actually hold the data, then first you change the type
of buf from void* to the correct data type (size_t in this case) and
then you pass fread the address of this object with
nread = fread(&p.buf, 1, sizeof p.buf, in);