C/C++ Delete File Contents by Roll Number | C++ Code for Deletion

  • Thread starter Thread starter Suyash Singh
  • Start date Start date
  • Tags Tags
    c++ delete file
AI Thread Summary
The discussion revolves around a C++ program intended to delete specific records from a binary file based on a roll number. The issue arises when the entire file is deleted instead of just the targeted records. Participants suggest debugging techniques, such as testing portions of the code, checking return values from file operations, and ensuring proper file handling. They emphasize the importance of error checking, correct input/output file modes, and the need for a debugger to step through the code. Additionally, methods for inserting data into a file without losing existing content are discussed, highlighting the challenges of direct insertion in standard C++ file streams.
Suyash Singh
ok i wrote my code but the whole file gets deleted instead of the required values.
Code:
    else if(option==5)
    {
              int rno;
              fstream w1;fstream e1;

              e1.open("temp.dat",ios::in|ios::out|ios::binary);
              w1.open("file.dat",ios::in|ios::out|ios::binary);

              cout<<"\nEnter roll number to delete";cin>>rno;

              bool value=false;

              while(w1.read((char*)&s1,sizeof(student)))
              {
                  if(s1.rno==rno)
                      value=true;
                  else
                       e1.write((char*)&s1,sizeof(student));
              }

              e1.close();
              w1.close();

              if ( value == false ) {
                  cout<<"\nNot found"<<endl;

              } else {
                   remove("file.dat");
                   rename("temp.dat","file.dat");
              }
    }
 
Last edited by a moderator:
Technology news on Phys.org
Have you tried running portions of your program?

- test the portion upto and including the two file closes, print value what happens?
- add prints to your while loop so you see how each line is handled
- test renaming file.dat instead of removing it to see if the rename works as expected

research the apis for remove and rename to see what they do and what problems they may have

You haven't provided enough detail about s1 and about student, using the sizeof function could mean you writing out nulls whereas it looks like s1 is a char array?

Do you have a debugger that you can run your program step by step?
 
  • Like
Likes Mark44
student is structure while s1 is the object of student
here is my complete code.
Code:
#include<iostream>
#include<fstream>
using namespace std;
struct student
{
    char name[80];
    int rno;
};
int main()
{
        student s1;
    int option,n;
    char ch;
    do
    {
    cout<<"Enter 1 to write file\nEnter 2 to read file\n3 to search file\n4 to modify file\n5 to delete";cin>>option;
    if(option==1)
    {
    ofstream f1;
    f1.open("file.dat",ios::binary);
    cout<<"Enter number of customers";cin>>n;
    for(int i=0;i<n;i++)
    {
    cout<<"\nEnter name(dot to terminate)";cin.getline(s1.name,80,'.');
    cout<<"\nEnter roll number";cin>>s1.rno;
        f1.write((char*)&s1,sizeof(student));
    }
      f1.close();
    }

    else if(option==2)
    {
           ifstream r1;
           r1.open("file.dat",ios::binary) ;
                while(   r1.read((char*)&s1,sizeof(student)))
           {
           cout<<"Name"<<s1.name<<endl;
           cout<<"Roll number"<<s1.rno<<endl;
           }
           r1.close();
    }

    else if(option==3)
    {
        int rno;
        cout<<"Enter roll number to search for";cin>>rno;
       bool condition=false;
        ifstream a1;
        a1.open("file.dat",ios::binary);
        while( a1.read((char*)&s1,sizeof(student)))
    {
        if (rno==s1.rno)
                {
                    condition=true;
                    cout<<"Name:"<<s1.name<<endl;
                    cout<<"Roll number"<<s1.rno<<endl;
                };
    }
    if(condition==false)
    cout<<"Not found"<<endl;
    a1.close();
    }

    else if(option==4)
    {
        int r;
        fstream q1;
        q1.open("file.dat",ios::in|ios::out|ios::binary);
        cout<<"Enter roll number to modify";cin>>r;
        bool flag=false;
        while(q1.read((char* )&s1,sizeof(student)))
        {
            if(s1.rno==r)
            {
                flag=true;
                cout<<"\nEnter new name(dot to end input)";cin.getline(s1.name,80,'.');
                cout<<"\nEnter roll number";cin>>s1.rno;
q1.write((char*)&s1,sizeof(student));
            }
        }
        if(!flag)
            cout<<"\nNot found"<<endl;
        q1.close();
    }
    else if(option==5)
    {
        int rno;
              fstream w1;fstream e1;
              e1.open("temp.dat",ios::in|ios::out|ios::binary);
              w1.open("file.dat",ios::in|ios::out|ios::binary);
              cout<<"\nEnter roll number to delete";cin>>rno;
              bool value=false;
              while(w1.read((char*)&s1,sizeof(student)))
              {
                  if(s1.rno==rno)
                      value=true;
                  else
                         e1.write((char*)&s1,sizeof(student));
              }
                                      e1.close();
              w1.close();
                             if(value==false)
                             {
                cout<<"\nNot found"<<endl;
                             }
                else
                {
                     remove("file.dat");
              rename("temp.dat","file.dat");
                }
    }

    cout<<"Do you want to continue?(y/n)";cin>>ch;
    }while((ch=='y')||(ch=='Y'));
               return 0;
}
 
To add to what @jedishrfu said, the remove() standard library function returns a value, which you are discarding. The return value is zero if this function succeeded in removing the file. If it failed, the function returns some nonzero value. The rename() standard library function works the same way, returning zero if it is successful and a nonzero value if it isn't.

Another problem that people run into when they're working with files is that if you don't provide the full path to the file, it needs to be in a directory that the program can find. For example, with Visual Studio, if you run your code in the debugger, the file has to be in the same directory as the source code. If you run your program from the command line, the file needs to be in the same directory as the executable. If you provide the full path to the file (which you aren't doing), it doesn't matter where the file is. Things are probably similar with other compilers.
 
  • Like
Likes jedishrfu
@Suyash Singh, the advice from jedishrfu about using a debugger is something you should think hard about doing. Using a debugger can answer a lot of questions.

Another problem that can come up is when your program inputs a mix of numbers and characters. Input from the keyboard is buffered, so when you press the 1 key, you're really pressing two keys -- the 1 key and the Enter key. If you program later is expecting a character (like y or n), the character that gets stored is actually the newline character ('\n') left over from when you entered a number. Using a debugger is very helpful in showing this.
 
Few points:

1) Error checking. You are not handling a single error in your entire program. f1.open can fail, as can rename, and remove.

2) Correct IO. You open both files with the flags ios::in|ios::out|ios::binary. For the output file ,you don't need ios::in and for the input file, you don't need ios::out.

3) Timing. remove() may return before the operating system cleans up the file. Give the OS a moment to clean up its buffers before trying to immediately to a rename.

Learn how to step through with GDB.
 
  • Like
Likes jedishrfu
Thank you, it’s always good to have problems like these and to thank everyone involved because each post builds up to the eventual solution and some of our advice may help you in the future even though you’ve yet to realize it.

Also really spend some time learning the language debugger tool. It will really save you in the future in ways too numerous to explain.
 
  • Like
Likes Suyash Singh
Unless I'm very sure about what I'm doing (i.e. I've done it a number of times before), I develop and test my code incrementally, with successive versions that do more things. I don't write the whole program in one shot and then start debugging it. In this case it would go something like this:

Version 1: Open the input file, read the data and simply display it.
Version 2: In addition, open the output file and write the data to it without modification or selection. That is, in effect, simply copy the file. Assuming the output file is supposed to be in the same format as the input file, I would test it by running the program again, using the output from the first run as input.
Version 3: Finally, add the selection logic for the records that you actually want to write.

At some point I would remove the data-display statements which are presumably not needed in the final product.
 
  • Like
Likes DrGreg and Suyash Singh
  • #10
I will learn debugger as soon as possible.
Also is it possible to add contents between already present data in a file.Like using 'ate' or 'app'.I mean is it possible?
Could anyone give me some sort of hint on how to begin?
 
  • #11
jtbell said:
Unless I'm very sure about what I'm doing (i.e. I've done it a number of times before), I develop and test my code incrementally, with successive versions that do more things. I don't write the whole program in one shot and then start debugging it. In this case it would go something like this:

Version 1: Open the input file, read the data and simply display it.
Version 2: In addition, open the output file and write the data to it without modification or selection. That is, in effect, simply copy the file. Assuming the output file is supposed to be in the same format as the input file, I would test it by running the program again, using the output from the first run as input.
Version 3: Finally, add the selection logic for the records that you actually want to write.

At some point I would remove the data-display statements which are presumably not needed in the final product.
i also prefer writing my code that way
 
  • #12
Suyash Singh said:
Also is it possible to add contents between already present data in a file.
As far as I can tell, at least with standard C++ file streams, you cannot insert new data directly into the middle of a file unless it actually replaces (overwrites) the same amount of existing data. To do a pure insert, keeping all the existing data intact, I think you have two choices:

Method 1:
  • Read the entire file into the program, using some kind of data structure (array, vector, list, etc.).
  • Insert the new data into the data structure.
  • Write the updated data structure into a new file.
  • Delete the old file (or rename it as a backup file) and rename the new one.
Method 2:
  • Read data from the old file and write it to a new file, up to the point where you want to insert the new data.
  • Write the new data to the new file.
  • Read the remaining data from the old file and write it to the new file.
  • Delete the old file (or rename it as a backup file) and rename the new one.
 
Last edited:
  • Like
Likes Suyash Singh
  • #13
you could use random file i/o but for the insert you'd need to read and write the data block following the insertion point much as you would if you were inserting into an array.

Another approach is to use some sorting of indexing scheme that is store your data as a linked list so that you can write the inserted data at the end of the file and adjust link nodes to find it. But this is a lot like reading from the old file, inserting the new data and then reading the remainder writing everythin to a new file. Also its marginally easier if your data blocks are of fixed size.

https://en.wikipedia.org/wiki/ISAM
 
  • Like
Likes Suyash Singh

Similar threads

Replies
33
Views
2K
Replies
8
Views
6K
Replies
75
Views
6K
Replies
17
Views
2K
Replies
2
Views
2K
Replies
4
Views
4K
Replies
17
Views
2K
Back
Top