Saving data

S

Simon

I'm trying to write a little function to save data. Basically I have a
large 2d array of structs, so I'm going to have to call the save
function once per struct in the array. I'd like to save the data using
fwrite(). After quite a lot of effort I've come up with the code
below, but I'm having real difficulty getting rid of the last error.
When compiling, I get this:

Line 52: "warning: assignment makes pointer from integer without a
cast"

I'm not sure what's causing this but it's very confusing. Can anyone
help?

Simon

--Code below--

#include <stdio.h>

struct test
{
char char1;
char char2;
char char3;
char char4;
int* pointer1;
int* pointer2;
};


main()
{
struct test test_st[3][3];
int i, j;
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
test_st[j].char1 = 1;
test_st[j].char2 = 1;
test_st[j].char3 = 1;
test_st[j].char4 = i;
test_st[j].pointer1 = NULL;
test_st[j].pointer2 = NULL;
}
}
FILE *fp = fopen ("test.csd_saved_game", "w");
struct test *p;
p = &test_st[j];
write_struct (fp, p);
/* p -> char1;
fwrite (p, 1, 1, fp);
fread (test_char, */
return 0;
}


write_byte (FILE *fp, unsigned char *temp, int bytes)
{
fwrite (temp, 1, bytes, fp);
}


write_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = p -> char1; <<<<ERROR IS HERE
write_byte (fp, temp, sizeof(char));
}
 
R

Richard Heathfield

Simon said:

Line 52: "warning: assignment makes pointer from integer without a
cast"
struct test
{
char char1;
char char2;
char char3;
char char4;
int* pointer1;
int* pointer2;
};
write_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = p -> char1; <<<<ERROR IS HERE

temp = (unsigned char *)& p -> char1;
write_byte (fp, temp, sizeof(char));

Or you could just do this: write_byte(fp, (unsigned char *)&p->char1, 1);

and lose temp completely.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
 
S

sam_cit

write_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = p -> char1; <<<<ERROR IS HERE
write_byte (fp, temp, sizeof(char));
}

Well, type of p->char1 is char but it is being assigned to a
character pointer, that doesn't make sense, it should be either one of
the following,

unsigned char temp;
temp = p -> char1;

or

unsigned char *temp;
temp = &(p ->char1);
 
S

Simon

I'm slowly making progress, but I'm still struggling with this...

I can now write successfully to a file, but I can't seem to get the
same values back that I've put in. I've copied the test program and
the sample output below. All I'm trying to do is to save the contents
of one array of structs to a file and then load them back into another
array of structs. The problem is that I'm not getting the same values
back. I'm worried that I'm missing something fundamental, so any
explanation would be really appreciated.

Thanks in advance

Simon


---- test program ----

/* Testing saving and loading */

#include <stdio.h>

struct test
{
char char1;
char char2;
char char3;
char char4;
int* pointer1;
int* pointer2;
};


main()
{
struct test test_st[3][3];
struct test test_s2[3][3];
int i, j;
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
test_st[j].char1 = i;
test_st[j].char2 = j;
test_st[j].char3 = i + j;
test_st[j].char4 = i * j;
test_st[j].pointer1 = NULL;
test_st[j].pointer2 = NULL;
}
}
printf ("Array initialised...\n");
for (i = 0; i < 3; i++)
printf ("test_st[%d][%d]: char1 = %d, char2 = %d, char3 = %d, char4 =
%d\n", i, i, test_st.char1, test_st.char2,
test_st.char3, test_st.char4);
FILE *fp = fopen ("test2.csd_saved_game", "w");
struct test *p;
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_st[j];
write_struct (fp, &p);
}
}
printf ("Data written...\n");
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_s2[j];
read_struct (fp, &p);
}
}
for (i = 0; i < 3; i++)
printf ("test_s2[%d][%d]: char1 = %d, char2 = %d, char3 = %d, char4 =
%d\n", i, i, test_s2.char1, test_s2.char2,
test_s2.char3, test_s2.char4);
return 0;
}


write_byte (FILE *fp, unsigned char *temp)
{
fwrite (temp, 1, 1, fp);
}


read_byte (FILE *fp, unsigned char *temp)
{
fread (temp, 1, 1, fp);
}


write_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = &(p -> char1);
write_byte (fp, temp);
temp = &(p -> char2);
write_byte (fp, temp);
temp = &(p -> char3);
write_byte (fp, temp);
temp = &(p -> char4);
write_byte (fp, temp);
}


read_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = &(p -> char1);
read_byte (fp, temp);
temp = &(p -> char2);
read_byte (fp, temp);
temp = &(p -> char3);
read_byte (fp, temp);
temp = &(p -> char4);
read_byte (fp, temp);
}


---- sample output ----

Array initialised...
test_st[0][0]: char1 = 0, char2 = 0, char3 = 0, char4 = 0
test_st[1][1]: char1 = 1, char2 = 1, char3 = 2, char4 = 1
test_st[2][2]: char1 = 2, char2 = 2, char3 = 4, char4 = 4
Data written...
test_s2[0][0]: char1 = 4, char2 = 0, char3 = 0, char4 = 0
test_s2[1][1]: char1 = -104, char2 = 55, char3 = 61, char4 = 0
test_s2[2][2]: char1 = -21, char2 = 6, char3 = -111, char4 = 124
 
B

Barry

Simon said:
I'm slowly making progress, but I'm still struggling with this...

I can now write successfully to a file, but I can't seem to get the
same values back that I've put in. I've copied the test program and
the sample output below. All I'm trying to do is to save the contents
of one array of structs to a file and then load them back into another
array of structs. The problem is that I'm not getting the same values
back. I'm worried that I'm missing something fundamental, so any
explanation would be really appreciated.

Thanks in advance

Simon


---- test program ----

/* Testing saving and loading */

#include <stdio.h>

struct test
{
char char1;
char char2;
char char3;
char char4;
int* pointer1;
int* pointer2;
};


main()
{
struct test test_st[3][3];
struct test test_s2[3][3];
int i, j;
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
test_st[j].char1 = i;
test_st[j].char2 = j;
test_st[j].char3 = i + j;
test_st[j].char4 = i * j;
test_st[j].pointer1 = NULL;
test_st[j].pointer2 = NULL;
}
}
printf ("Array initialised...\n");
for (i = 0; i < 3; i++)
printf ("test_st[%d][%d]: char1 = %d, char2 = %d, char3 = %d, char4 =
%d\n", i, i, test_st.char1, test_st.char2,
test_st.char3, test_st.char4);
FILE *fp = fopen ("test2.csd_saved_game", "w");
struct test *p;
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_st[j];
write_struct (fp, &p);
}
}
printf ("Data written...\n");
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_s2[j];
read_struct (fp, &p);
}
}
for (i = 0; i < 3; i++)
printf ("test_s2[%d][%d]: char1 = %d, char2 = %d, char3 = %d, char4 =
%d\n", i, i, test_s2.char1, test_s2.char2,
test_s2.char3, test_s2.char4);
return 0;
}


write_byte (FILE *fp, unsigned char *temp)
{
fwrite (temp, 1, 1, fp);
}


read_byte (FILE *fp, unsigned char *temp)
{
fread (temp, 1, 1, fp);
}


write_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = &(p -> char1);
write_byte (fp, temp);
temp = &(p -> char2);
write_byte (fp, temp);
temp = &(p -> char3);
write_byte (fp, temp);
temp = &(p -> char4);
write_byte (fp, temp);
}


read_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = &(p -> char1);
read_byte (fp, temp);
temp = &(p -> char2);
read_byte (fp, temp);
temp = &(p -> char3);
read_byte (fp, temp);
temp = &(p -> char4);
read_byte (fp, temp);
}


---- sample output ----

Array initialised...
test_st[0][0]: char1 = 0, char2 = 0, char3 = 0, char4 = 0
test_st[1][1]: char1 = 1, char2 = 1, char3 = 2, char4 = 1
test_st[2][2]: char1 = 2, char2 = 2, char3 = 4, char4 = 4
Data written...
test_s2[0][0]: char1 = 4, char2 = 0, char3 = 0, char4 = 0
test_s2[1][1]: char1 = -104, char2 = 55, char3 = 61, char4 = 0
test_s2[2][2]: char1 = -21, char2 = 6, char3 = -111, char4 = 124


Among other problems.
You need to heed your compiler warnings, one of them is causing
a bug.
 
S

Simon

Barry said:
Among other problems.
You need to heed your compiler warnings, one of them is causing
a bug.

I don't get any compiler warnings when I compile the program which is
why I'm finding the problem so difficult to solve. The second set of
data printed to the screen is not consistent - it's different each time
the program is run. That makes me think that fread() is not reading
the data in correctly, but I can't see what's wrong with my code.

Simon
 
B

Barry

Simon said:
I don't get any compiler warnings when I compile the program which is
why I'm finding the problem so difficult to solve. The second set of
data printed to the screen is not consistent - it's different each time
the program is run. That makes me think that fread() is not reading
the data in correctly, but I can't see what's wrong with my code.

Simon

You need to crank up the warning level on your compiler. If it won't
spit out at least 10 you need a new compiler.

Barry
 
B

Bill Pursell

Simon said:
I'm slowly making progress, but I'm still struggling with this...

I can now write successfully to a file, but I can't seem to get the
same values back that I've put in. I've copied the test program and
the sample output below. All I'm trying to do is to save the contents
of one array of structs to a file and then load them back into another
array of structs. The problem is that I'm not getting the same values
back. I'm worried that I'm missing something fundamental, so any
explanation would be really appreciated.

Among other things, you are opening the file for writing, so
your reads will generally not work. Also, if you want to
read from the beginning of the file, you need to rewind the
file. You will also need to flush the file after you've done
the writes to ensure that the reads will work.
 
B

Barry

Simon said:
I don't get any compiler warnings when I compile the program which is
why I'm finding the problem so difficult to solve. The second set of
data printed to the screen is not consistent - it's different each time
the program is run. That makes me think that fread() is not reading
the data in correctly, but I can't see what's wrong with my code.

Simon

Oops, I sent the message before I finished replying. Before you fread()
you need to get back to the start of the file. Look at rewind() or fseek().
 
F

Flash Gordon

Simon said:
I don't get any compiler warnings when I compile the program which is
why I'm finding the problem so difficult to solve. The second set of
data printed to the screen is not consistent - it's different each time
the program is run. That makes me think that fread() is not reading
the data in correctly, but I can't see what's wrong with my code.

Well, if you tell your compiler to conform to a C standard (either one)
it is required to produce at least one diagnostic. What it diagnoses
will depend on the standard you choose. So, currently, your code is in a
language that is not quite C.

C90, the standard most commonly fully implemented, does not allow
declarations after the first statement in a block. I.e. the following is
not allowed:
{
int i;
i = 0;
int j;

In C99, the current standard which is implemented in only a very few
compilers (gcc has a C99 mode, but the GCC team admit that it is not yet
C99 conforming) then you have to at least declare function before you
use them. It also removes implicit int, so your declaration of
main()
is no longer legal. So, if we fix all these problems so you have
prototypes before you call the functions and do not declare variables
after a statement and don't use implicit int you get code any compiler
will complain about, even gcc without any options. I've also sorted the
indentation which was lost somewhere (don't use tabs for indentation
when posting to news groups) and declared functions as void where they
do not return anything:

/* Testing saving and loading */

#include <stdio.h>

struct test
{
char char1;
char char2;
char char3;
char char4;
int* pointer1;
int* pointer2;
};

void write_byte (FILE *fp, unsigned char *temp);
void read_byte (FILE *fp, unsigned char *temp);
void write_struct (FILE *fp, struct test *p);
void read_struct (FILE *fp, struct test *p);

int main(void)
{
struct test *p;
struct test test_st[3][3];
struct test test_s2[3][3];
int i, j;
FILE *fp = fopen ("test2.csd_saved_game", "w");
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
test_st[j].char1 = i;
test_st[j].char2 = j;
test_st[j].char3 = i + j;
test_st[j].char4 = i * j;
test_st[j].pointer1 = NULL;
test_st[j].pointer2 = NULL;
}
}
printf ("Array initialised...\n");
for (i = 0; i < 3; i++)
printf ("test_st[%d][%d]: char1 = %d, char2 = %d"
", char3 = %d, char4 = %d\n",
i, i, test_st.char1, test_st.char2,
test_st.char3, test_st.char4);
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_st[j];
write_struct (fp, &p);
}
}
printf ("Data written...\n");
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_s2[j];
read_struct (fp, &p);
}
}
for (i = 0; i < 3; i++)
printf ("test_s2[%d][%d]: char1 = %d, char2 = %d,"
" char3 = %d, char4 = %d\n",
i, i, test_s2.char1, test_s2.char2,
test_s2.char3, test_s2.char4);
return 0;
}


void write_byte (FILE *fp, unsigned char *temp)
{
fwrite (temp, 1, 1, fp);
}


void read_byte (FILE *fp, unsigned char *temp)
{
fread (temp, 1, 1, fp);
}


void write_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = &(p -> char1);
write_byte (fp, temp);
temp = &(p -> char2);
write_byte (fp, temp);
temp = &(p -> char3);
write_byte (fp, temp);
temp = &(p -> char4);
write_byte (fp, temp);
}


void read_struct (FILE *fp, struct test *p)
{
unsigned char *temp;
temp = &(p -> char1);
read_byte (fp, temp);
temp = &(p -> char2);
read_byte (fp, temp);
temp = &(p -> char3);
read_byte (fp, temp);
temp = &(p -> char4);
read_byte (fp, temp);
}

Now that I've got your code to the point where the compiler will
complain about it, fix the issues the compiler complains about. They are
serious errors. Also, find out how to get your compiler to conform to a
C standard and also enable such other warnings as it can provide. If
using gcc, for example, as a bare minimum compile with
gcc -ansi -pedantic -Wall

Please everyone note, the above code is not mine and I would never have
written it. If you quote it please make it clear that it is not my code.
 
S

Simon

Flash said:
[lots of excellent advice]

Thanks very much for this advice - it's exactly the sort of thing that
I need when learning c. By getting into the right habits now I'll save
myself a lot of hassle later.

Simon
 
A

Andrew Poelstra

I don't get any compiler warnings

Maybe this will help:

gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion
-Wwrite-strings -Wno-conversion -O3 comp.lang.c

comp.lang.c:15: warning: return type defaults to ‘int’
comp.lang.c:15: warning: function declaration isn’t a prototype
comp.lang.c: In function ‘main’:
comp.lang.c:33: error: missing terminating " character
comp.lang.c:34: error: expected expression before ‘%’ token
comp.lang.c:34: error: stray ‘\’ in program
comp.lang.c:34: error: missing terminating " character
comp.lang.c:35: warning: format not a string literal and no format arguments
comp.lang.c:36: warning: ISO C90 forbids mixed declarations and code
comp.lang.c:43: warning: implicit declaration of function ‘write_struct’
comp.lang.c:43: warning: nested extern declaration of ‘write_struct’
comp.lang.c:52: warning: implicit declaration of function ‘read_struct’
comp.lang.c:52: warning: nested extern declaration of ‘read_struct’
comp.lang.c:56: error: missing terminating " character
comp.lang.c:57: error: expected expression before ‘%’ token
comp.lang.c:57: error: stray ‘\’ in program
comp.lang.c:57: error: missing terminating " character
comp.lang.c:58: warning: format not a string literal and no format arguments
comp.lang.c: At top level:
comp.lang.c:64: warning: return type defaults to ‘int’
comp.lang.c:64: warning: no previous prototype for ‘write_byte’
comp.lang.c:70: warning: return type defaults to ‘int’
comp.lang.c:70: warning: no previous prototype for ‘read_byte’
comp.lang.c:76: warning: return type defaults to ‘int’
comp.lang.c:76: warning: no previous prototype for ‘write_struct’
comp.lang.c: In function ‘write_struct’:
comp.lang.c:78: warning: pointer targets in assignment differ in signedness
comp.lang.c:80: warning: pointer targets in assignment differ in signedness
comp.lang.c:82: warning: pointer targets in assignment differ in signedness
comp.lang.c:84: warning: pointer targets in assignment differ in signedness
comp.lang.c: At top level:
comp.lang.c:90: warning: return type defaults to ‘int’
comp.lang.c:90: warning: no previous prototype for ‘read_struct’
comp.lang.c: In function ‘read_struct’:
comp.lang.c:92: warning: pointer targets in assignment differ in signedness
comp.lang.c:94: warning: pointer targets in assignment differ in signedness
comp.lang.c:96: warning: pointer targets in assignment differ in signedness
comp.lang.c:98: warning: pointer targets in assignment differ in signedness

Those errors were there without the special flags, which suggests that
they weren't just spurious // comments.
 
F

Flash Gordon

Andrew said:
Maybe this will help:

gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion
-Wwrite-strings -Wno-conversion -O3 comp.lang.c

comp.lang.c:15: warning: return type defaults to ‘int’
comp.lang.c:15: warning: function declaration isn’t a prototype
comp.lang.c: In function ‘main’:
comp.lang.c:33: error: missing terminating " character

Those errors were there without the special flags, which suggests that
they weren't just spurious // comments.

The errors without flags, such as the one I left in above, where due to
line wrapping of string literals. I know because I used gcc for my
compilations as well. Something you should watch out for when copying
code from posts. However, you are correct that there were a number of
real problems in the code that your compilation flags (of even fewer
flags) show up.
 
M

Mark McIntyre

I don't get any compiler warnings when I compile the program which is
why I'm finding the problem so difficult to solve.

Search your compiler options for a means of turning on the warnings
then. I'd guess you have it in the default level which warns for very
little.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
D

Dietmar Schindler

Bill said:
... Also, if you want to
read from the beginning of the file, you need to rewind the
file. You will also need to flush the file after you've done
the writes to ensure that the reads will work.

N1124, 7.19.5.3 The fopen function
6 ... output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning
function (fseek, fsetpos, or rewind), ...
 

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

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top