Re: Saving data



Simon wrote:
Barry wrote:
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.

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][i].char1 = i;
test_st[j][i].char2 = j;
test_st[j][i].char3 = i + j;
test_st[j][i].char4 = i * j;
test_st[j][i].pointer1 = NULL;
test_st[j][i].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[i][i].char1, test_st[i][i].char2,
test_st[i][i].char3, test_st[i][i].char4);
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_st[j][i];
write_struct (fp, &p);
}
}
printf ("Data written...\n");
for (j = 0; j < 3; j++)
{
for (i = 0; i < 3; i++)
{
p = &test_s2[j][i];
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[i][i].char1, test_s2[i][i].char2,
test_s2[i][i].char3, test_s2[i][i].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.
--
Flash Gordon
.



Relevant Pages

  • Re: Converting code from single to double precision
    ... int VarHasData; ... void PrintFortranLine (char *s); ... int continuedFormat = FALSE; ... char temp; ...
    (comp.lang.fortran)
  • Re: Replacing fgets
    ... Even if u_int8_t is a typedef for unsigned char, ... Didn't your compiler complain here. ... offset is changed ... offset needs to be an int. ...
    (comp.lang.c)
  • Re: How to use a C++ class in .NET
    ... > absolutely compiler dependant. ... > public ref class MyClass ... > int funtion1(unsigned char* inBuffer, unsigned inType, unsigned char* ...
    (microsoft.public.dotnet.framework)
  • Re: How to use a C++ class in .NET
    ... absolutely compiler dependant. ... public ref class MyClass ... int funtion1(unsigned char* inBuffer, unsigned inType, unsigned char* ...
    (microsoft.public.dotnet.framework)
  • Re: querry related to structure padding
    ... char B; ... The compiler is still free to insert padding between B and C, ...
    (comp.lang.c)