Удаление конкретной строки из файла в c ++ - PullRequest
0 голосов
/ 21 сентября 2019

Я хочу использовать ввод числа ученика, а затем внутри своего файла я хочу удалить эту конкретную запись.Допустим, мой файл содержит следующую информацию

1 Абхи 92

2 Рави 89

3 Киран 45

Пользователь вводит 2, затем я хочу файлизменить на

1 Абхи 92

3 Киран 45

Как это возможно?

РЕДАКТИРОВАТЬ:

Это частьэтого проекта, я хочу создать еще один случай, который говорит удалить

#include<iostream>
#include<stdlib.h>
#include<fstream>
using namespace std;
class Students
    {
        private:

            int roll_number;
            char name[80],dummy;
            float marks;
            char grade;
        public:
            void read_info()
            {
                calc_grade();
                cout<<roll_number<<"\t"<<name<<"\t\t\t"<<marks<<"\t\t"<<grade<<endl<<endl;
            }
            void write_info()
            {
                cout<<"Roll Number: ";
                cin>>roll_number;
                cin.get(dummy);
                cout<<"Name: ";
                cin.get(name,80);
                cin.get(dummy);
                start:
                cout<<"Marks: ";
                cin>>marks;
                if(marks < 0 || marks > 100)
                {
                    cout<<"Invalid"<<endl;
                    goto start;
                }
                cin.get(dummy);
            }
            void calc_grade()
            {
                if(marks>=80)
                    grade = 'A';
                else if(marks>=60)
                    grade = 'B';
                else if(marks>=40)
                    grade = 'C';
                else if(marks>=20)
                    grade = 'D';
            }
            int return_roll()
            {
                return roll_number;
            }
            float return_marks()
            {
                return marks;
            }
    };
int main()
    {
        int start_swit;
        do
        {
            system("pause");
            system("cls");
            cout<<"\t\t\t\t\tStudents Database"<<endl;
            cout<<"------------------------------------------------------------------------------------------------------------------------"<<endl;
            cout<<"------------------------------------------------------------------------------------------------------------------------"<<endl;
            Students s;
            fstream fil;
            char ch;
            int search_rn;
            cout<<"1.Read\t\t2.Write\t\t3.Specific student\t\t4.Topper"<<endl<<endl;
            cin>>start_swit;
            switch(start_swit)
                {
                case 1:
                    {
                        system("cls");
                        fil.open("studentdata.bin",ios::in|ios::binary);
                        cout<<"Roll.N\t  Name\t\t\tMarks\t\tGrade"<<endl;
                        cout<<"-----------------------------------------------------"<<endl;
                        while(fil.read((char*)&s,sizeof(s)))
                        {
                            s.read_info();
                        }
                        fil.close();
                        break;
                    }
                case 2:
                    {
                        system("cls");
                        fil.open("studentdata.bin",ios::in|ios::out|ios::binary|ios::app);
                        ch = 'y';
                        do{
                            s.write_info();
                            fil.write((char*)&s,sizeof(s));
                            cout<<"Do you want to enter more records?: ";
                            cin>>ch;
                        }
                        while(ch == 'y');
                        fil.close();
                        break;
                    }
                case 3:
                    {
                        int found = 0;
                        fil.open("studentdata.bin",ios::in|ios::binary);
                        cout<<"Enter the roll number of the student: ";
                        cin>>search_rn;
                        while(fil.read((char*)&s,sizeof(s)))
                              {
                                  if(search_rn == s.return_roll())
                                  {
                                      cout<<"Roll.N\t\tName\t\tMarks\t\tGrade"<<endl;
                                      cout<<"-----------------------------------------------------"<<endl;
                                      s.read_info();
                                      found = 1;
                                      break;
                                  }
                              }
                        if(found != 1)
                            cout<<"Student not found"<<endl;
                        fil.close();
                        break;
                    }
                case 4:
                    {
                        float highest_marks = 0;
                        int roll_high;
                        fil.open("studentdata.bin",ios::in|ios::binary);
                        while(fil.read((char*)&s,sizeof(s)))
                            {
                                if(s.return_marks()>= highest_marks)
                                    {
                                            highest_marks = s.return_marks();
                                            roll_high = s.return_roll();
                                    }
                            }
                        fil.close();
                        fil.open("studentdata.bin",ios::in|ios::binary);
                        while(fil.read((char*)&s,sizeof(s)))
                              {
                                  if(roll_high == s.return_roll())
                                  {
                                      cout<<"Roll.N\t\tName\t\tMarks\t\tGrade"<<endl;
                                      cout<<"-----------------------------------------------------"<<endl;
                                      s.read_info();
                                      break;
                                  }
                              }
                        fil.close();
                        break;
                    }

                }//switch end
            }// Do while loop end
            while(start_swit>=1 && start_swit<=4);
        return 0;
    }// main() end

Ответы [ 2 ]

0 голосов
/ 21 сентября 2019

Если вы хотите отредактировать файл на месте, то есть, не загружая весь файл в память, не редактируя его и не перезаписывая старый файл, вы можете использовать методы произвольного доступа, чтобы перезаписать информацию об удаленном ученике фиктивной информациейэто не будет прочитано.Это немного загромождает ваш файл.Я не тестировал этот код, но основная идея - использовать функции-члены seekg и tellg в fstream.

case 5:
    {
        int found = 0;
        long pos;   //stores file pointer position
        fil.open("studentdata.bin",ios::in|ios::binary);
        cout<<"Enter the roll number of the student to delete: ";
        cin>>search_rn;
        while(fil.read((char*)&s,sizeof(s)))
              {
                  if(search_rn == s.return_roll())
                  {
                      //returns file's write position
                      pos = fil.tellp();
                      //rewind the file pointer (sizeof type????)
                      fil.seekg((pos - sizeof(s)), ios::cur); //not ios::beg);
                      s.delete_info();
                      //overwrite the old date with dummy data
                      fil.write((char*)&s,sizeof(s));
                      fil.close();
                      found = 1;
                      break;
                  }
              }
        if(found != 1)
            cout<<"Student not found"<<endl;
        fil.close();
        break;
    }

//add this class method:
void delete_info() 
{
    roll_number = -1;
    name = "deleted";
    marks = 0.0;
    grade = ' ';
}

Опять же, этот код не проверен, но я думаю, что смещение корректно, еслитак как sizeof (s) возвращает long.Возможно, было бы чище выполнить полную операцию чтения файла в память, редактирования и перезаписи, как предлагает приведенный выше ответ.

0 голосов
/ 21 сентября 2019

Вот один метод:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

int deleteAtLine(const std::string file_name, std::vector::size_type lineNumber){
    //the memory storage medium
    std::vector<std::string> lines;
    //Reading the file to the storage
    {
        //opening the file for reading from it
        std::ifstream file(file_name);
        //checking if the file has been opened correctly
        if (not file.is_open()) {
            std::cerr << "can't open the file " << file_name << std::endl;
            return -1;
        }
        //Reading
        for (std::string one_line; std::getline(file, one_line);lines.push_back(one_line));
    }
    //Writing the storage to the file
    {
        //opening the file for writing to it
        std::ofstream file(file_name);
        //checking if the file has been opened correctly
        if (not file.is_open()) {
            std::cerr << "can't open the file " << file_name << std::endl;
            return -1;
        }
        //finding out the number of the lines
        const auto lines_count = lines.size();
        //writing
        for (std::string::size_type lines_counter(0); lines_counter < lines_count;){
            //checking the line number and writing the extra line if it is needed
            if(lines_counter != lineNumber) file << lines[lines_counter++] << std::endl;
        }
    }
    //returning 0 if there was no error to this stage 
    return 0;
}

Сначала вы открываете файл для чтения:

        //opening the file for reading from it
        std::ifstream file(file_name);
        //checking if the file has been opened correctly
        if (not file.is_open()) {
            std::cerr << "can't open the file " << file_name << std::endl;
            return -1;
        }

, затем читаете все строки файла и сохраняете их в векторе:

        //Reading
        for (std::string one_line; std::getline(file, one_line);lines.push_back(one_line));

после закрытия предыдущей (доступной только для чтения) версии файла вы снова открываете его для записи, на этот раз:

        //opening the file for writing to it
        std::ofstream file(file_name);
        //checking if the file has been opened correctly
        if (not file.is_open()) {
            std::cerr << "can't open the file " << file_name << std::endl;
            return -1;
        }

, затем возвращаете все строки, кроме нужной:

        for (std::string::size_type lines_counter(0); lines_counter < lines_count;){
            //checking the line number and writing the extra line if it is needed
            if(lines_counter != lineNumber) file << lines[lines_counter++] << std::endl;
}

Вы можете использовать эту функцию следующим образом:

int main(int argc, char* argv[]) {

    std::string file_name;
    std::string::size_type lineNumber;

    std::cin >> file_name;
    std::cin >> lineNumber;

    return deleteAtLine(file_name, lineNumber);
}

Удачи!

...