[comp.lang.c] Structure hopping

mark@tfsg.UUCP (Mark Crafts) (01/03/91)

Forgive my ignorance, but is there a quick 'n' simple way to say,
dump a structure to a file (or whatever) using pointers, if we
know that the structure only consists of, (for example) chars?
I would think that you could assign a pointer to the beginning
of the structure, and (assuming structures are set up linearly)
hop down the list.  This question also brings up another one...
if this can be done, how do we know when to stop aside from
hardcoding a certain number of iterations?

For example, assume we have a structure like this:

struct grandpa_structure {
	char	data1[30];
	char	data2[23];
		.
		.
		.
	char	data95[12];
};

struct grandpa_structure mr_structure;

In other words, a structure that would be really annoying to write
out one field at a time.
I would LIKE to be able to do something like this:

(assume mr_structure to be filled in somehow)

char	*struct_ptr;
	.
	.
struct_ptr = mr_structure
while (struct_ptr != "whatever it is that signals the end of a structure") {
	putc (*struct_ptr, fp);
}

All responses are appreciated.
			Mark

gallag@hpanui.HP.COM (Mike Gallagher) (01/04/91)

> dump a structure to a file (or whatever) using pointers, if we
> I would LIKE to be able to do something like this:
> char	*struct_ptr;
> struct_ptr = mr_structure
> while (struct_ptr != "whatever it is that signals the end of a structure") {
> 	putc (*struct_ptr, fp);
> }

Try this:

char *struct_ptr, *end_ptr;

struct_ptr = (char *)&mr_structure;
               /*    ^ note the missing & above */

end_ptr = struct_ptr + sizeof(mr_structure);

while (struct_ptr != end_ptr) {
    putc (*struct_ptr++, fp);
}

Mike

mike@bria.AIX (Mike Stefanik/78125) (01/04/91)

In article <949@tfsg.UUCP> mark@tfsg.UUCP (Mark Crafts) writes:
>Forgive my ignorance, but is there a quick 'n' simple way to say,
>dump a structure to a file (or whatever) using pointers, if we
>know that the structure only consists of, (for example) chars?
[proceeds to describe a structure]

Actually, there is a very simple way to do this; consider the following:

struct foo {
		int	anumber;
		long	along;
		char	somestring[64];
		float	areal;
		char	anotherstring[128];
		} bar;

funwithfoo()
{
int	fd;

	/* here we open a file named "datafile"; this usage opens the
	   file for reading and writing, appending to the file if it
	   exits, otherwise creating it */

	if ( (fd = open("datafile",O_RDWR|O_CREAT|O_APPEND,0644)) == -1 ) {
		fprintf(stderr,"Bad karma dude!  I cannot create datafile\n");
		exit(1);
		}

	/* here we write the contents of 'bar' out to the file we just opened;
	   note the & operator that provides us with the address of 'bar',
	   which is sizeof(struct foo) bytes */

	write(fd,&bar,sizeof(struct foo));

	/* here we close our file */

	close(fd);

	/* now, let's reopen the file, and sequentially read through the
	   records that we have written (perhaps in the past?) */

	if ( (fd = open("datafile",O_RDONLY)) == -1 ) {
		fprintf(stderr,"Bad karma dude!  Datafile doesn't exist!\n");
		exit(1);
		}

	while ( read(fd,&bar,sizeof(struct foo)) == sizeof(struct foo) ) {
		/* here we display the guts of struct foo */
		};

	close(fd);
}

Forgive any typos, etc.  Hopefully you'll get the picture.

-----------------------------------------------------------------------------
Michael Stefanik, Systems Engineer (JOAT), Briareus Corporation
UUCP: ...!uunet!bria!mike
"If it was hard to code, it should be harder to use!"

staff@cadlab.sublink.ORG (Alex Martelli) (01/04/91)

mark@tfsg.UUCP (Mark Crafts) writes:
	...
:Forgive my ignorance, but is there a quick 'n' simple way to say,
:dump a structure to a file (or whatever) using pointers, if we
:know that the structure only consists of, (for example) chars?

fwrite((char*)pointer, sizeof(*pointer), 1, stdout), or similar, should
do in many such cases ("holes" between members may be slight nuisances).
-- 
Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 53, Bologna, Italia
Email: (work:) staff@cadlab.sublink.org, (home:) alex@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; 
Fax: ++39 (51) 366964 (work only), Fidonet: 332/401.3 (home only).