I am thinking about manually deleting records which have grades[5] under 5.I haven' t tried anything yet, because I don' t know where to start.I don't want a function that does the job quick, I want to implement myself a function and understand it, but I don't know how to delete records in relative files. My code should work like this:- the binary file should receive data from the text file and show the searched student, if the student doesn't exists I should add it . After all of this I should be able to delete students that have grade[5] strictly under 5. It is just the deletion function that is missing from my code.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
typedef struct {
int nrm; //enrolment number - works as relative key
char CNP[14]; //string ASCIIZ
char nume[30]; //string
int an; //study year
int grupa; //group
unsigned char note[20]; //grades
char is;//this is status indicator
} STUDENT;
int filesize(FILE* f, int rec_size)
{//from the crt.pos substract one and i ll know the record of...
long crt_pos;
int size;
//below compute the size of the file in records, withouth altering the crt.pozition
crt_pos = ftell(f);//save the current pozition in a var, before going to the end of the file
fseek(f, 0, SEEK_END);//go to the end of the file
size = ftell(f) / rec_size;//ftell gives the current position and the dim of the record
fseek(f, crt_pos, SEEK_SET);//ne readuce la positia curenta, initiala pe care am salvat o n var
return size;
}
void main()
{
char numefr[30] = "..\\Studenti_r_f.dat";//why \\? changes the meaning of the foll char; afiseaza un singur
FILE* f;
STUDENT x;//record variable
int i, key, dim;//key=key for the record;dim=size of file in records
//dim changes when computing the sizeof(file), at every iteration
fopen_s(&f, numefr, "wb+");
//optionally preform the file
freopen("..\\input.txt", "rt", stdin); //remove if reading data from keyboard and uncomment the printf lines
//printf("Enrollment number: ");
scanf_s("%d", &key);//read the first field, always the 1 field is the key
while (!feof(stdin))//process the key read another and so on
{
//check key range
dim = filesize(f, sizeof(STUDENT));//dim=nr de studenti din fisier;nr de recorduri;
//check the poz indicated by the key, it may have changed since the last iteration
if (key >= dim)//if the key=10, position 10 doesn t exist
{ //extend the file
x.is = 0;
fseek(f, 0, SEEK_END);//go to the end of file and write this record
for (i = 0; i < key - dim; i++)
fwrite(&x, sizeof(STUDENT), 1, f);
}
fseek(f, key * sizeof(STUDENT), SEEK_SET);//change the pos in the file, go to the pos indicated by the key
fread(&x, sizeof(STUDENT), 1, f);//read rec from file
if (x.is == 1)//if is=1, the position is taken, it must always be 0
printf("\nError: duplicate key %d. Skipping.", key);//read rest of field for student, write record from file then
else
{
x.nrm = key;
//printf_s("Name: ");
gets_s(x.nume);
gets_s(x.nume);
//printf_s("CNP: ");
gets_s(x.CNP);
//printf_s("Year: ");
scanf_s("%d", &x.an);
//printf_s("Group: ");
scanf_s("%d", &x.grupa);
for (i = 0; i < 20; i++)
//x.note[i]=0;
scanf_s("%d", &x.note[i]);
x.is = 1;
//the cur poz is after this record before we write the fseek, which brings us to the beginning of this record
fseek(f, key * sizeof(STUDENT), SEEK_SET);//ne aduce la inceputul recordului nou adaugat;
fwrite(&x, sizeof(STUDENT), 1, f);//write a record
}//everything repets with a new key
//printf_s("Enrollment number (or CTRL+Z): ");
scanf_s("%d", &key);
}
fclose(f);
fclose(stdin);
printf("\nDone. File <%s> was created. Press a key.", numefr);
_getch();
}
there are two ways to remove a record from a file:
1) copy into a new file all the records before the one to be deleted, skip the record to be deleted, then copy all the rest of the records then delete the original file then rename the new file to the original file name.
2) step through the file until find the record to be deleted. Then, in a loop copy the next record to the current record then truncate the file by 1 record length
All that (above) can be very messy and time consuming. Suggest: just set the field 'is' in the record to be 'deleted' to 0