I have spent quite a lot time attempting to find a solution how to write and read structure to/from file and completely get stuck.
The code should be very simple, but I think I've missed quite important details about fwrite
/fread
. I think write is working but I am not completely sure. Once I try to read into array I get segmentation fault error on the k=1
.
I would be ultimately happy if someone could guide me in what direction should I move further.
#include <stdio.h>
struct Student {
char matrikl[6];
char shortName[6];
int value1;
int value2;
int value3;
int value4;
int money;
}xStudent;
int calcMoney(int,int,int,int);
int main(void)
{
int i=0;
printf("How much students to insert!\n");
scanf("%i",&i);
struct Student S[i];
for (int var = 0; var < i; ++var) {
printf("insert student data\n");
printf("Matriklinumber\n");
scanf("%s", S[var].matrikl);
printf("Student name\n");
scanf("%s", S[var].shortName);
printf("Insert values!\n");
scanf("%i%i%i%i",&S[var].value1,&S[var].value2,&S[var].value3,&S[var].value4);
S[var].money=calcMoney(S[var].value1,S[var].value2,S[var].value3,S[var].value4);;
}
FILE*sourcefile;
sourcefile=fopen("text.txt","ab+");
for (int var = 0; var < i; ++var) {
fwrite(&S[var],sizeof(struct Student),1,sourcefile);
}
fclose(sourcefile);
sourcefile=fopen("text.txt","rb+");
struct Student A[i];
if (sourcefile==NULL) perror ("Error opening file");
else
{
int k=0;
while (fgetc(sourcefile) != EOF) {
fread(&A[k],sizeof(struct Student),1,sourcefile);
k++;
}
}
fclose(sourcefile);
return 0;
}
int calcMoney(int xvalue1, int xvalue2, int xvalue3, int xvalue4)
{
int Sum = xvalue1+xvalue2+xvalue3+xvalue4;
if(Sum==20)
return 100;
else
if(Sum>=16 && Sum<20)
return 75;
else return 0;
}
You have the right idea, but this should fix your problem.
for (int var = 0; var < i; ++var) {
fwrite(&S[i], sizeof(struct Student), 1, sourcefile);
}
The argument 1 in fwrite
after the sizeof
statement indicates you only want to add one Student at a time.
Please see the doc for fwrite
: http://www.cplusplus.com/reference/cstdio/fwrite/
And also:
while (fgetc(sourcefile) != EOF) {
fread(&A[k], sizeof(struct Student), 1, sourcefile);
k++;
}
Please see the doc for fread
: http://www.cplusplus.com/reference/cstdio/fread/
I know it's the cplusplus website, but it's the only place I could find good docs on the functions.
Also, the below array initializes to 0 elements:
struct Student A[k];
You may want to try managing a linked list for this instead.
Might end up looking something like:
struct StudentList {
struct Student* student;
struct StudentList* next;
};
struct StudentList* students = NULL;
while(!feof(sourcefile)) {
struct StudentList* newlink = malloc(sizeof(struct StudentList));
newlink->student = malloc(sizeof(struct Student));
newlink->next = NULL;
fread(newlink->student, sizeof(struct Student), 1, sourcefile);
if(NULL != students) {
struct StudentList* iter;
for(iter=students;
NULL != iter->next;
iter = iter->next); // iterate to last link
iter->next = newlink; // add new link to the end
} else students = newlink; // add new link to the beginning
}
Then to free your list, just use something like:
struct StudentList* iter, *head;
for(iter=students;
NULL != iter;)
{
head = iter;
free(iter->student);
free(iter);
iter = head;
}