Другие языки программирования и технологии

Как удалить определённые строки в текстовом файле? С++

Надо удалить все строки, в которых flat[i].Anulat == "Yes".
#include
#include
#include
using namespace std;

struct Apartment
{
int CodOfert;
string Sector;
int NrOdai;
int NrEtaj;
int AriaS;
float Pret;
string Telefon;
string Anulat;
string AdresA;
} flat[25];

void ReadOfInformation1()
{
ifstream f ("Oferte.txt");
int i = 0;
while (!f.eof())
{
f >> flat[i].CodOfert >> flat[i].Sector >> flat[i].NrOdai >> flat[i].NrEtaj >> flat[i].AriaS >> flat[i].Pret >> flat[i].Telefon >> flat[i].Anulat >> flat[i].AdresA;
i++;
}
number = i - 1;
f.close();
}
void ShowOfInformation1()
{
cout << setw(95) << "* ДОСТУПНЫЕ ПРЕДЛОЖЕНИЯ *: " << endl;
cout << "__________________________________________________________________________________________________________________________________________________________________ " << endl;
cout << "Код: \t\t Район: \t\t Кол-во комнат: \t Кол-во этажей: \tОбщая площадь: \tСтоимость: \tЕсть телефон: \tАннулировано: \t Адрес:" << endl;
cout << "__________________________________________________________________________________________________________________________________________________________________ " << endl;
for (int i = 0; i < number; i++)
{
cout << flat[i].CodOfert << " \t\t " << flat[i].Sector << " \t\t " << flat[i].NrOdai << " \t\t " << flat[i].NrEtaj<< " \t\t" << flat[i].AriaS << " \t\t" << flat[i].Pret << " \t\t" << flat[i].Telefon << " \t\t" << flat[i].Anulat << " \t\t " << flat[i].AdresA << endl;
cout << "__________________________________________________________________________________________________________________________________________________________________ " << endl;
}
}
int FindOfPosition1(string str)
{
for (int i = 0; i < number; i++)
if (flat[i].Anulat == str)
return i;
return -1;
}
void DeleteOfInformation1()
{
string temporary = "Yes";
int position = FindOfPosition1(temporary);
if (position == -1)
cout << "Предложения приняты. " << endl;
else
{
for (int i = position; i < number - 1; i++)
flat[i].Anulat = flat[i + 1].Anulat;
number--;
FileRewrite1();
}
}

int main ()
{
setlocale (LC_ALL, "Russian");
int choice, i = 0;
cout << setw(40) << "* МЕНЮ: * " << endl;
cout << endl;
do
{
cout << endl;
cout << "************************************************************************* " << endl;
cout << "0 - Выйти. " << endl;
cout << "1 - Показать информацию о доступных предложениях. " << endl;
cout << "3 - Удалить строки, которые аннулированы клиентом. " << endl;
int choice;
cout << endl;
cout << "Укажите Ваш выбор: ";
cin >> choice;
cout << endl;
switch (choice)
{
case 0 :
return 0;
case 1 :
{
ReadOfInformation1();
ShowOfInformation1();
break;
}
case 2 :
{
ReadOfInformation1();
while (flat[i].Anulat == "Yes")
DeleteOfInformation1();
break;
}
default :
cout << "Такого номера в меню нет! Выберите другой номер из предложенного меню. " << endl;
break;
}
}
while (choice != 0);
}
Это база данных, и если одному из клиентов что-то не понравилось, вовсе не означает, что и все остальные с ним солидарны. Поэтому, что в базу данных попало, то храниться там настолько долго, что можно сказать навсегда. Для удаления данных из таблицы используется флаг bool hidden, который выставляется в true, если элемент «удалён», что позволяет скрывать данные. Это позволяет без проблем восстанавливать удалённые данные.

В вашем случае клиент работает не с файлом данных, а с объектом выборки в виде коллекции (предлагаю использовать std::set). Вот из неё он имеет право удалять всё что захочет. При сохранении выбора достаточно имя клиента связать с уникальным идентификатором данных в запросе. Таким образом, если база данных представлена единственным текстовым файлом, то каждая запись начинается с id, который уникален и вставляется автоматически при добавлении новой записи данных в базу.

Также следует иметь таблицу клиентов, которая хранит их выбор в виде строки id разделённых пробелом, по которым будет выполняться запрос из основной таблицы. Следует предусмотреть возможность редактирования своего выбора клиентом.

Вывод. Архитектура вашего приложения не выдерживает критики.
VM
Vlad Mastyulev
79 809
Лучший ответ
Ошибка в удалении (DeleteOfInformation1) у Вас в том, что Вы пытаетесь найти только одну строку.
Вам нужен цикл в цикле. Во внешнем поиск, во внутреннем сдвиг (при нахождении). А так в принципе похоже.
Пример простого цикла с удалением в массиве. Ситуация как у Вас.
https://www.ideone.com/M2k1kL

Проще было использовать vector, конечно.

struct foo {
string anulat;
int value;
};
и
vector< foo > v;
v.erase(remove_if(v.begin(),v.end(),[](auto& item) {return item.anulat=="Yes";}), v.end());

более полный рабочий пример:
https://www.ideone.com/u6I7xY
Владимир Дзюба
Владимир Дзюба
84 764
Олег Потешкин Спасибо большое.