Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > struct and pointer question

Reply
Thread Tools

struct and pointer question

 
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-14-2012
"Bill Cunningham" <> writes:
<snip>
> #include <stdio.h>
>
> struct param {
> char *infile;
> char *outfile;
> void *buf;
> };
>
> #include "p.h"


I wonder what's in here?

> 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);


That size if wrong. The code may well work, but that's not a sensible
size to use.

> nwrite = fwrite(p.buf, 1, nread, out);
> }
> while (!feof(in));
> fclose(in);
> fclose(out);
> printf("%zu %zu\n", nread, nwrite);
> 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 *
> how would I choose that in a file calling main? Say I want buf to be a
> size_t for example.


I read this about a dozen times and finally I think I worked it out.
The trouble is that you ask how do so what you think is needed when
that's not what's needed at all.

I think you want a function that can read int one time and chars the
next. Other times you might want it to read size_ts or even something
else like doubles. To do that, you don't change the type of the buffer,
you change the size of the data being read. But (and it's a big but)
this only works if the data you are reading is in the right format.
You've posted questions about reading various file formats in the past
so I can't tell if reading the data using fread is appropriate or not.

Of course, at some point you need the data to be in a C object of the
right type. You might read one or more ints using fread into a generic
buffer, but you need to process them as ints. That may be, ultimately
what you are asking, but the answer to how you do that is not
substantially different to the answer to the question "how do I write a
program?".

--
Ben.
 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      09-14-2012
On Fri, 14 Sep 2012 14:41:02 -0400, "Bill Cunningham"
<> wrote:

>Barry Schwarz wrote:
>
>> I wonder what fread will do with a char* when it is expecting a FILE*
>> as the fourth argument.

>
> I didn't notice that error. It's not in my code either. I don't seem to
>be making myself clear. I will post some code later when I get the time. If
>that doesn't work I'll go from there.


You change your code at random so we have no idea what is in it now
but it certainly was in the code you originally posted as shown below:

>> struct param {
>> * * char *infile;
>> * * char *outfile;
>> * * void *buf;};


>> * *fread(p.buf,1,sizeof p.buf,p.infile);


--
Remove del for email
 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      09-14-2012
On Fri, 14 Sep 2012 17:31:28 -0400, "Bill Cunningham"
<> wrote:

>Angel wrote:
>> It's pretty clear that you have no idea what you're talking about or
>> what you are doing, yes. You've asked about fread() and fwrite()
>> several times now and you still don't seem to understand what these
>> functions do.

>
>[snip]
>
>I write successful code with fread and fwrite all the time.


Strange that you never post any of this successful code when asking a
question. Or did I miss the smiley?

--
Remove del for email
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      09-14-2012
On Fri, 14 Sep 2012 17:29:00 -0400, "Bill Cunningham"
<> wrote:

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

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


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

>size_t for example.


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);

--
Remove del for email
 
Reply With Quote
 
Angel
Guest
Posts: n/a
 
      09-14-2012
On 2012-09-14, Bill Cunningham <> wrote:
> Angel wrote:
>> It's pretty clear that you have no idea what you're talking about or
>> what you are doing, yes. You've asked about fread() and fwrite()
>> several times now and you still don't seem to understand what these
>> functions do.

>
> [snip]
>
> I write successful code with fread and fwrite all the time.


Given your utter confusion about basic concepts just about every time
you post here, I strongly doubt that. Last time you asked about them
you didn't even know what their return code meant.

But maybe I am mistaken. Try posting some actual code next time you ask
a question, instead of some half-baked lines that wouldn't even compile.


--
"C provides a programmer with more than enough rope to hang himself.
C++ provides a firing squad, blindfold and last cigarette."
- seen in comp.lang.c
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      09-14-2012
On 2012-09-14, Angel <angel+> wrote:
> On 2012-09-14, Bill Cunningham <> wrote:
> It's pretty clear that you have no idea what you're talking about or


That has been clear for pretty much the entire decade since Cunningham
started posting to comp.lang.c. Someone posting under the name "Bill
Cunningham:" evidently first appeared on July 4, 2002.

Assuming it is even the same person posting under that name, the passage
of ten years leaves him yet grappling with the same beginner issues.

Some people who have university degrees now and working as developers
were elementary school kids in 2002.

The idiot regulars in this newsgroup keep responding to Cunningham, like
predictable drones. (You know what they say about endlessly repeating the same
action, expecting different results.)
 
Reply With Quote
 
Bill Cunningham
Guest
Posts: n/a
 
      09-14-2012
Ben Bacarisse wrote:
> "Bill Cunningham" <> writes:
> <snip>
>> #include <stdio.h>
>>
>> struct param {
>> char *infile;
>> char *outfile;
>> void *buf;
>> };
>>
>> #include "p.h"

>
> I wonder what's in here?


The above.

>
>> 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);

>
> That size if wrong. The code may well work, but that's not a sensible
> size to use.


OK

>
>> nwrite = fwrite(p.buf, 1, nread, out);
>> }
>> while (!feof(in));
>> fclose(in);
>> fclose(out);
>> printf("%zu %zu\n", nread, nwrite);
>> 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 * how would I choose that in a file calling main?
>> Say I want buf to be a size_t for example.

>
> I read this about a dozen times and finally I think I worked it out.
> The trouble is that you ask how do so what you think is needed when
> that's not what's needed at all.
>
> I think you want a function that can read int one time and chars the
> next. Other times you might want it to read size_ts or even something
> else like doubles.


Yes! Yes! I hoped I could cross the usenet understanding barrier. This post
is not directly related to the fread fwrite functions I just happened to use
them so I can get used to them. Personally I like fgetc and fputc.

To do that, you don't change the type of the
> buffer, you change the size of the data being read. But (and it's a
> big but) this only works if the data you are reading is in the right
> format. You've posted questions about reading various file formats in
> the past so I can't tell if reading the data using fread is
> appropriate or not.


I've been reading binary data. Jpeg format.

> Of course, at some point you need the data to be in a C object of the
> right type. You might read one or more ints using fread into a
> generic buffer, but you need to process them as ints. That may be,
> ultimately what you are asking, but the answer to how you do that is
> not substantially different to the answer to the question "how do I
> write a program?".


True.

Bill


 
Reply With Quote
 
Bill Cunningham
Guest
Posts: n/a
 
      09-14-2012
Angel wrote:
> It's pretty clear that you have no idea what you're talking about or
> what you are doing, yes. You've asked about fread() and fwrite()
> several times now and you still don't seem to understand what these
> functions do. (As well as generic confusion about structures,
> functions, and return values.)
>
> fread() reads objects from a stream into memory. fwrite() writes
> objects from memory into a stream. In both cases, it is your job to
> provide the following information to the function:
> 1. The location in memory to read from or write to.
> 2. The size of one single object, in bytes.
> 3. The number of objects to be read or written.
> 4. The stream to read from or write to.
>
> The first argument of fread() and fwrite() is of type void* because
> these functions can be used to read or write any kind of object, hence
> you can pass any type of pointer to it. It's your duty to pass a
> pointer that matches with your needs. (If you are reading char
> objects, use a pointer to char. If you're writing structures, pass a
> pointer to a structure.)
>
> Here is a very simple example of a program that writes some structures
> to a file:
>
>
> #include <stdio.h>
>
> struct Person
> {
> char name[20];
> unsigned int age;
> };
>
> int main(void)
> {
> struct Person people[] = { { "John", 34u },
> { "Dick", 48u },
> { "Harry", 25u } };
>
> FILE *file = fopen("people.db", "wb");
> fwrite(people, sizeof (people[0]), 3, file);
> fclose(file);
> }


This thread has nothing to do with fread or fwrite.

Bill


 
Reply With Quote
 
Angel
Guest
Posts: n/a
 
      09-14-2012
On 2012-09-14, William Ahern <> wrote:
> Kaz Kylheku <> wrote:
>> On 2012-09-14, Angel <angel+> wrote:
>> > On 2012-09-14, Bill Cunningham <> wrote:
>> > It's pretty clear that you have no idea what you're talking about or

>
>> That has been clear for pretty much the entire decade since Cunningham
>> started posting to comp.lang.c. Someone posting under the name "Bill
>> Cunningham:" evidently first appeared on July 4, 2002.

>
> Bill explained long ago that he had a mental illness. It's not possible to
> tell if he's really a troll. Mental illness is a pretty good cover story.
> And 10+ years would make for an extraordinarily long troll, even if by
> multiple persons.
>
> If people want to spend their time answering his questions, so be it. It's
> not skin off your back.


As trolls go, he's fairly benign. His questions are at least on topic,
and even if he doesn't learn from the answers he's given, others might.
As far as I can tell he has yet to throw a tantrum, and his posting
volume is fairly low. I'd wish more trolls were like him.


--
"C provides a programmer with more than enough rope to hang himself.
C++ provides a firing squad, blindfold and last cigarette."
- seen in comp.lang.c
 
Reply With Quote
 
Bill Cunningham
Guest
Posts: n/a
 
      09-14-2012
Ben Bacarisse wrote:

> I read this about a dozen times and finally I think I worked it out.
> The trouble is that you ask how do so what you think is needed when
> that's not what's needed at all.
>
> I think you want a function that can read int one time and chars the
> next. Other times you might want it to read size_ts or even something
> else like doubles. To do that, you don't change the type of the
> buffer, you change the size of the data being read.

[snip]

Problem solved. Thanks Much.

Bill


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Struct pointer vs. struct array pointer aleksa C Programming 16 02-20-2013 08:20 PM
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
(: Pointer to struct withing pointer to struct :) Zero C Programming 16 11-19-2005 01:27 AM
passing pointer->struct->pointer->struct to function. .. ?? beetle C Programming 2 01-25-2005 06:08 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments