LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   c++ file processing -- how to remove a record from a file (https://www.linuxquestions.org/questions/programming-9/c-file-processing-how-to-remove-a-record-from-a-file-235066/)

sharonyiisl 09-25-2004 09:00 AM

c++ file processing -- how to remove a record from a file
 
i am writing a c++ program to add, view, modify, and delete records from a ".dat" file.

for example, "student.dat" file containing fields: stud_no, name, etc.
i use struct student {} to store information of a student, then write to the file.

what are the codes should i use to allow user to remove a particular record? (i.e: remove the record with stud_no: 12345)

thank you if anyone willing to help me.

Hko 09-25-2004 11:48 AM

Just removing a block of bytes from a file is not possible. One solution to this is:
  • Rename the file to student.OLD
  • In a loop: copy the structs one-by-one to a new student.dat file, while skipping the one to remove (with of something like: "if (stud.stud_no == 12345) continue")
  • Remove student.OLD.

A faster but more complex option may be to "memory map" the file with the "mmap()" system-call. The mmap() function loads the file into memory, so you can read/write to the structs as if it were an array.

The fastest way will probably be to use mmap(), and not actually remove the struct, but to mark it as removed by setting stud_no of the struct-to-remove to 0 (or -1 if that suits you better). This way the struct is not really removed from the file, and the file will keep the same size. Also you'll need the rest of your program to detect the stud_no that are 0.

Maybe it is also possible (I'm not quite sure about this) to really remove the struct by using mmap(). E.g. when you found the (mmapped) array-index of the struct you want to remove to be 3, then copy the structs remaining in the file (index 4 and up) to fill the gap. Something like:
Code:

for (i=0; i < arraylen-1; ++i) {
    mmapped_student[ i ] = mmapped_student[ i+1 ]
}

Then, when you're done removing structs, munmap() the file with the length being n times sizeof(struct student) less than the original length of the file. (n being the number of removed structs).

To read more on mmap() and munmap(), see "man mmap", and the book "Advanced Linux Programming" (by New Riders publishing), chapter 5. This book is downloadable freely from http://www.advancedlinuxprogramming.com/ (one PDF file per chapter)

aluser 09-25-2004 01:21 PM

If the order of the structs in the file doesn't matter, you could just copy the last struct in the file over the deleted one, then truncate after the second-to-last struct. See fseek(3) and friends.

sharonyiisl 09-26-2004 12:03 AM

modify a record in student.dat
 
Thank you very much.

Another question:
what are the codes to allow user to modify a record, for example, modify the record with stud_no 1234 to stud_no 2323? why when i modify a record using the following codes, that record(1234) does not changed. but it will insert the information(2323) as a new record at the end of student.dat?

My coding is like the follow:

void main()
{
.....
.....
cout<<"Enter the stud_no of the record you want to modify: ";
cin>>stuno;
modify(stuno);
}

void modify(int stuno)
{
student s;
fstream file;
file.open("student.dat", ios::app|ios::out|ios::in);

int count = findloc(stuno);

cout<<"\nDo you want to modify this record? (Y/N) ";
cin>>choice;

int location = (count - 1 ) * sizeof(s);


if(tolower(choice) == 'y')
{
cout<<"Enter stud_no:";
cin>>s.stud_no;
cout<<"Enter name: ";
cin>>s.name;
.....
.....
file.seekp(location);
file.write((char *) &s, sizeof(s));
}
}

int findloc(int stuno)
{
student s;
int n, endposition, count = 0;
fstream file;
file.open("student.dat", ios::app|ios::out|ios::in);
file.seekg(0, ios::end);
endposition = file.tellg();
n = endposition / sizeof(s);
file.seekg(0);
file.read((char *) &s, sizeof(s));
while(file.eof() == 0)
{
count++;

if(s.stud_no == stuno)
break;
file.read((char *) &s, sizeof(s));
}

if(count - 1 == n)
{
cout<<"There is no record with stud_no ("<<stuno<<")"<<endl<<endl;
}

file.close();

return count;
}

acid_kewpie 09-26-2004 03:54 AM

I am having a bit of difficulty believing that this is not just your homework... not least because it's abuot students. if this is work assigned to you as part of an educational program, please do not ask for help about it here.

http://www.linuxquestions.org/rules.php


All times are GMT -5. The time now is 02:59 PM.