fread fwrite struct

J

janssenssimon

//de structure om de highscores in op de slagen
typedef struct score{
char *naam;
int veld;
int score;
struct score *volg;
}HIGH;


void toonhighscores(void)
{
int i=6;
FILE* f;
HIGH* h;

f=fopen("high.bin","rb");

clrscr();

//als er al highscores zijn,...
if(f)
{
printf("HIGHSCORES\n----------\n\nNaam");
gotoxy(30,4);
printf("Veld");
gotoxy(38,4);
printf("Score\n\n");

h=malloc(sizeof(HIGH));
fread(h, sizeof(HIGH), 1, f);
while(!feof(f))
{
printf("%s", h->naam);
gotoxy(30,i);
printf("%.2d", h->veld);
gotoxy(38,i++);
printf("%.2d\n", h->score);

fread(h, sizeof(HIGH), 1, f);
}
free(h);
fclose(f);
}
//als er nog geen highscores zijn,...
else
printf("Nog geen highscores aanwezig in het spel\n");

printf("\nDruk op een toets om terug te keren naar het menu.");
getch();
}

//schrijft de gespeelde highscores van dit spel weg
void schrijfweg_highscores(char *naam, int size, int zetten)
{
int geschreven=0;
FILE *f;
HIGH *h, *kop=NULL, *staart=NULL, *n;

f=fopen("high.bin", "rb");

if(f)
{
h=malloc(sizeof(HIGH));
fread(h, sizeof(HIGH), 1, f);
while(!feof(f))
{
//alles in lezen in een structure
//die later terug wordt geschreven in een nieuw bestand
h->volg=NULL;
if(kop)
staart->volg=h;
else
kop=h;
staart=h;
h=malloc(sizeof(HIGH));
fread(h, sizeof(HIGH), 1, f);
}

fclose(f);
f=fopen("high.bin","wb");

for(h=kop; h; h=h->volg)
{
if(!(strcmp(h->naam,naam)) && h->veld==size && h->score>zetten)
{
//als de nieuwe data vorige data moet overschrijven
h->score=zetten;
geschreven=1;
}
fwrite(h, sizeof(HIGH), 1, f);
}

//als de nieuwe data nog niet in het bestand zit
if(!geschreven)
{
n=malloc(sizeof(HIGH));
n->naam=naam;
n->veld=size;
n->score=zetten;
n->volg=NULL;
fwrite(n, sizeof(HIGH), 1, f);
free(n);
}
}
else
{
//als er nog niets in het bestand staat, moeten de scores van het
gespeelde spel erin komen
h=malloc(sizeof(HIGH));
h->naam=naam;
h->veld=size;
h->score=zetten;
h->volg=NULL;
f=fopen("high.bin", "wb");
fwrite(h, sizeof(HIGH), 1, f);
}

//bestand afsluiten
fclose(f);

//geheugen vrijmaken
if(kop)
for(h=kop; h;)
{
h=kop->volg;
free(kop);
kop=h;
}
else
free(h);
}




This is my code, but the problem is that when you close and open the
entire programme it can't printf any of the highscores, or write them
away for that matter. Non of the 2 functions are completely finished.
Why does this happen and what can I do about it??


Dit is mijn code, maar het probleem is dat hij de highscores de eerste
maal dat het programma gerunt wordt allemaal tegoei wegschrijft ed.
Maar als je het programma afsluiten en terug opent kan hij geen van de
2 functies nog tegoei afsluiten. Er worden geen waarden meer geprint.
Hoe komt dit en wat kan ik er aan doen?
 
M

Michael Mair

> This is my code, but the problem is that when you close and open the
> entire programme it can't printf any of the highscores, or write them
> away for that matter. Non of the 2 functions are completely finished.
> Why does this happen and what can I do about it??

Please state your problem before giving us your code -- this way
we can read your code with the problem in mind.
If you state your problem, do it systematically:
- What are you trying to do?
- What have you achieved yet?
- Where do you have problems? What are these problems? What would
you have expected?

After reading your description I know that you seem to have
problems with reading to or writing from files. That is not very
much.
//de structure om de highscores in op de slagen

Note that C++/C99 line comments have disadvantages for code
posted to a newsgroup -- if lines wrap around, something different
may happen -- or your code does not compile.
Even if I assume C99, then your code does not compile because at
least
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
is missing.
If you do not give a complete, compiling piece of code illustrating
your problem, then say so. It is, however, possible that the main
problems are in the part you do not show us.

typedef struct score{
char *naam;
int veld;
int score;
struct score *volg;
}HIGH;


void toonhighscores(void)
{
int i=6;

Why 6? Magic numbers are usually a bad idea.
Use a symbolic constant instead.
FILE* f;
HIGH* h;

f=fopen("high.bin","rb");

clrscr();

Undeclared function.
//als er al highscores zijn,...
if(f)
{
printf("HIGHSCORES\n----------\n\nNaam");
gotoxy(30,4);
printf("Veld");
gotoxy(38,4);
printf("Score\n\n");

h=malloc(sizeof(HIGH));

You forgot to check whether h != NULL -- otherwise,
you must not continue.
fread(h, sizeof(HIGH), 1, f);
while(!feof(f))
{
printf("%s", h->naam);

h->naam is a pointer. You cannot store a pointer to a file during
one run of your program and retrieve it in a meaningful way during
another run.
You must store the actual _string_.
gotoxy(30,i);

Unknown function.
printf("%.2d", h->veld);
gotoxy(38,i++);
printf("%.2d\n", h->score);

fread(h, sizeof(HIGH), 1, f);
}
free(h);
fclose(f);
}
//als er nog geen highscores zijn,...
else
printf("Nog geen highscores aanwezig in het spel\n");

printf("\nDruk op een toets om terug te keren naar het menu.");
getch();

Unknown function.
}

//schrijft de gespeelde highscores van dit spel weg
void schrijfweg_highscores(char *naam, int size, int zetten)
{
int geschreven=0;
FILE *f;
HIGH *h, *kop=NULL, *staart=NULL, *n;

f=fopen("high.bin", "rb");

if(f)
{
h=malloc(sizeof(HIGH));
fread(h, sizeof(HIGH), 1, f);
while(!feof(f))
{
//alles in lezen in een structure
//die later terug wordt geschreven in een nieuw bestand
h->volg=NULL;
if(kop)
staart->volg=h;
else
kop=h;
staart=h;
h=malloc(sizeof(HIGH));
fread(h, sizeof(HIGH), 1, f);
}

fclose(f);
f=fopen("high.bin","wb");

for(h=kop; h; h=h->volg)
{
if(!(strcmp(h->naam,naam)) && h->veld==size && h->score>zetten)
{
//als de nieuwe data vorige data moet overschrijven
h->score=zetten;
geschreven=1;
}
fwrite(h, sizeof(HIGH), 1, f);
}

//als de nieuwe data nog niet in het bestand zit
if(!geschreven)
{
n=malloc(sizeof(HIGH));
n->naam=naam;
n->veld=size;
n->score=zetten;
n->volg=NULL;
fwrite(n, sizeof(HIGH), 1, f);
free(n);
}
}
else
{
//als er nog niets in het bestand staat, moeten de scores van het
gespeelde spel erin komen
h=malloc(sizeof(HIGH));
h->naam=naam;
h->veld=size;
h->score=zetten;
h->volg=NULL;
f=fopen("high.bin", "wb");
fwrite(h, sizeof(HIGH), 1, f);
}

//bestand afsluiten
fclose(f);

//geheugen vrijmaken
if(kop)
for(h=kop; h;)
{
h=kop->volg;
free(kop);
kop=h;
}
else
free(h);
}

Consider writing everything into a text file, one line per struct
component. This makes testing etc. much easier.
Then decide whether you want to have arbitrary length strings or
whether you restrict your string length.
In the latter case, change the declaration of "naam" to
char naam[MAX_NAAM_LENGTH+1];
where the "+1" accommodates for the string terminator.
Otherwise, you need a function which can read lines of arbitrary length
and allocates sufficient memory for the string read.

Only with fixed length strings, you can read in the entries from
a binary file blockwise.
However, if you had printed everything as text to the file, you
would either have found your conceptual error earlier or would not
have introduced in the first place.


Cheers
Michael
 
J

janssenssimon

The code given is but a piece of complete code
All the nececary includes are included
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

witch also have such functions as clrscr() and gotoxy()

The thing I am trying to achief with this code toonhighscores is:
printf of a structure under the titles Naam, Score, Veld

And the thing I'm trying to achief with the code schrijfweg_highscores
is:
reading a existing binairy file into a structure (linked list).
adding one structure to the linked list
and writing the entire linked list to the overwritten file high.bin

The problem I'm having with this piece of code is:
The first time I run the program, everything works, the reading, the
writing, adding, everything
but if you then close the program, and reopen it, non of the 2 function
work
while I don't see what the difference is with the first the program
runs,...

If you want me to sent entire source of the project, please say so,...
 
M

Mark McIntyre

The code given is but a piece of complete code

unfortunately, I suspect its the wrong piece. The problem is probably
somewhere else.
The problem I'm having with this piece of code is:
The first time I run the program, everything works, the reading, the
writing, adding, everything
but if you then close the program, and reopen it, non of the 2 function
work
while I don't see what the difference is with the first the program
runs,...

If you want me to sent entire source of the project, please say so,...

please don't. Instead
- create a small test programme which demonstrates your problem.
- make it really small, remove everything unneccessary
- by now, you may have solved your problem
- if not, ask again.

Mark McIntyre
 
M

Michael Mair

The code given is but a piece of complete code
All the nececary includes are included
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

witch also have such functions as clrscr() and gotoxy()

<conio.h> and <windows.h> are not standard C -- my compiler
and library combination just does not have them.

The thing I am trying to achief with this code toonhighscores is:
printf of a structure under the titles Naam, Score, Veld

After first having read it from a file.
And the thing I'm trying to achief with the code schrijfweg_highscores
is:
reading a existing binairy file into a structure (linked list).
adding one structure to the linked list
and writing the entire linked list to the overwritten file high.bin

Thank you, this confirms my guesses.

The problem I'm having with this piece of code is:
The first time I run the program, everything works, the reading, the
writing, adding, everything
but if you then close the program, and reopen it, non of the 2 function
work
while I don't see what the difference is with the first the program
runs,...

I actually answered the question: Your problem is that you store
pointers/addresses (HIGH.naam) in a file. As soon as your programme
terminates, these are no longer valid. If you restart the programme and
read in the addresses, there probably is not the same content in the
old location -- worse still, you access memory that does not belong
to your programme. You must store what the pointer points to, the
actual _content_. In this case, a string.
Thus the suggestion to switch from storing your stuff as binary to
storing it as text in a text file -- this can easily be inspected
and errors can be found.

If you want me to sent entire source of the project, please say so,...

No, this is not necessary for _this_ problem.
If you have further problems, try to reduce the version of your
programme you post here to the absolute minimum that still shows
the problem and compiles.

Please quote enough context so that other people know what is
going on -- this gives them a better chance to help you, too.


Cheers
Michael
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top