Как удалить элемент из файла c
Перейти к содержимому

Как удалить элемент из файла c

  • автор:

Как удалить элемент из файла c

Функция поиска по фамилии:

void SearchInDB() < FILE *f = fopen("db.txt", "rb"); FILE *num = fopen("num.txt", "rb"); if (f == NULL || num == NULL) < system("cls"); printf("\nНе удалось открыть файл базы данных"); printf("\nНажмите любую клавишу для выхода в меню"); getch(); >else < struct record recz[100]; int i, kol; fread((int*)&kol, 1, sizeof(kol), num); //заполнение массива записями из файла for (i = 0; i < kol; i++) < fseek(f, sizeof(recz[i])*i, 0); fread((char*)&recz[i], 1, sizeof(recz[i]), f); >int z, s = 0; char surn[12]; cin >> surn; system("cls"); printf("Поиск абонентов с фамилией %s", surn); for (z = 0; z < kol; z++) < if (strcmp(surn, recz[z].surn) == 0) < printf("\n\nЗапись №%i", recz[z].num); printf("\nФИО ->%s %s %s", recz[z].surn, recz[z].name, recz[z].patronymic); printf("\nНомер телефона -> %i", recz[z].tel); s++; > > if (s == 0) < printf("\n\nНе найдено абонентов с фамилией %s ", surn); >if (s == 1) < printf("\n\nБольше абонентов не найдено"); >> fclose(f); fclose(num); >

И аналогичные функции добавления абонента, создание базы данных и её просмотра (при необходимости выложу). Но никак не могу разобраться с функцией удаления абонента из базы данных (любым способом: по фамилии, по телефону или номеру, неважно).
Подскажите пожалуйста, как её реализовать?

Вот мой набросок:

void DelFromDB() < FILE *f = fopen("db.txt", "ab"); FILE *num = fopen("num.txt", "r+b"); if (f == NULL || num == NULL) < system("cls"); printf("\nНе удалось открыть файл базы данных"); printf("\nНажмите любую клавишу для выхода в меню"); getch(); >else < struct record recz[100]; int i, kol, c = 0, s = 0; fread((int*)&kol, 1, sizeof(kol), num); for (i = 0; i < kol; i++) < fseek(f, sizeof(recz[i])*i, 0); fread((char*)&recz[i], 1, sizeof(recz[i]), f); >printf("\nВведите № записи абонента, которого нужно удалить\n"); int number = getch(); for (int z = 0; z < kol; z++) < if (recz[z].num == number) < // и дальше тупик. >> fclose(f); fclose(num); > >

Заранее спасибо за любую помощь!

Последний раз редактировалось Alena_Sw; 02.12.2016 в 21:11 .

Как удалить элемент из файла c

пожалуйста, не переносите тему, т.к форум С++ не посещаем.

в общем привожу кусок кода:

// вырезка из функции
if ((tf=fopen(«product/file1.dat»,»rb+»)) != NULL)
<
printf(» Enter part number: «);

while (!feof(tf))
<
if (strcmp(prod.pn,goods)==0)
<
// каким образом можно удалить из файла текущую запись?
break;
>
fread(&prod,sizeof(prod),1,tf);
>
fclose(tf);

автор: Волки (20.10.2009 в 10:22) письмо автору

файл это не база данных, «просто удалить» касательно файла имеет примерно следующий алгоритм:
* найти удаляемый кусок,
* прочитать оставшийся файл до конца,
* записать поверх удаляемого куска.
Если удаляются несколько записей, то проще в озу сформировать данные для файла, и потом его переписать полностью

автор: psychomc (20.10.2009 в 10:28) письмо автору

запись удаляется только одна, я уже и так и так пробовал. но как говорится — «как-то не удалось». поэтому пошёл на крайности и начал флудить на этом форуме. примерчик какой-нибудь не подкините? гугл мне не помог.

автор: Trianon (20.10.2009 в 10:35) письмо автору

Зависит от организации данных внутри файла.
Например, можно прочитать из файла последнюю запись, записать её на место удаляемой, после чего укоротить файл по позиции начала последней записи.

fread, fwrite, fseek, ftell, ftruncate

автор: psychomc (20.10.2009 в 14:10) письмо автору

извиняюсь, не увидел вашего сообщения.
начало понятно, только объясните плиз смысл и как реализуется вот это:
>после чего укоротить файл по позиции начала последней записи
?

автор: Trianon (20.10.2009 в 17:14) письмо автору

>извиняюсь, не увидел вашего сообщения.

>начало понятно, только объясните плиз смысл и как реализуется вот это:
>>после чего укоротить файл по позиции начала последней записи
>?

если запись из файла удалена, значит файл должен стать на одну запись короче, так?

Это смысл.
А реализация. переносимой реализации некоторое время назад не было. Возможно, нету и сейчас. Тут надо смотреть инструментарий выбранной среды исполнения. То есть набор функций работы с файлами, которым можно пользоваться.
http://www.google.ru/search?hl=ru&q=ftruncate

автор: psychomc (20.10.2009 в 17:32) письмо автору

>Модератора благодарите. 🙂
а я думал это я слепой, и что Вы ничего не предложили а решили поиздеваться 🙂

>если запись из файла удалена, значит файл должен стать на одну запись короче, так?
согласен
но это всё барахло делаю в borland c++ 3.1, и в Help’е не вижу такой функции и соответвенно не понимаю как её юзать. в гугле пока тоже ничего не нарыл.
такое чувство что придется заходить с другой стороны 🙁
просто сначала хотелось как можно проще и грамотнее реализовать. тот вариант что написал Волки я вообще не понял.

автор: psychomc (20.10.2009 в 17:43) письмо автору

прочитал на одном форуме:

>А по старинке файл срезали записью в него 0 байт. Ну, т.е. lseek(где_резать); write(file, buf, 0);

скажите, такое пройдет?

автор: psychomc (20.10.2009 в 17:50) письмо автору

а, всё, нашёл, функция chsize 🙂
буду пытаться 🙂
в любом случае — спасибо Вам за идею

автор: psychomc (21.10.2009 в 12:25) письмо автору

// переходим на начало строки
fseek(tf,-s,1);

// сохраняем текущее значение указателя
curpos = ftell(tf);

// переходим в конец файла
fseek(tf, 0L, SEEK_END);

// переходим на начало последней строки
fseek(tf,-s,1);

// считываем последнюю запись
fread(&savezap, s, 1, tf);

// возвращаем указатель на перезаписываемую запись
fseek(tf, curpos, SEEK_SET);

// записываем последнюю запись на место удаляемой
fwrite(&savezap[0], s, 1, tf);

// дескриптор файла
handle = fileno(tf);

// размер файла
fs = filelength(handle);

всё было как бы не так и сложно 🙂
огромное спасибо Trianon-у!

автор: Trianon (20.10.2009 в 10:34) письмо автору

>Если удаляются несколько записей, то проще в озу сформировать данные для файла, и потом его переписать полностью

Это , блин, ни разу не проще, чтоб не сказать — невозможно.
В контексте любых нормальных исполняющих сред предполагается, что объем данных в файле всяко в оперативную память не полезет.

автор: psychomc (20.10.2009 в 10:36) письмо автору

у меня это не актульно. нужно просто сдать курсовой

>* найти удаляемый кусок,
>* прочитать оставшийся файл до конца,
>* записать поверх удаляемого куска.

вот этот вариант мне подходит. но пока не получается реализовать

автор: Волки (20.10.2009 в 11:54) письмо автору

prod *oneGoods = new prod;
while (!eof(file)) <
fread(oneGoods, sizeof(prod), 1, file);
if ( strcmp(strId, oneGoods->pn)==0)
<
// найден нужный элемент, удалим
fseek(file, 0L, SEEK_END);
int size = ftell (file);
fseek (file, 0, SEEK_SET);

size -= ftell(file); //размер оставшегося файла
char *buffer = new char[ size ];
fread (buffer, size, 1, file);
fseek (file, -sizeof(prod), SEEK_SET);
fwrite (buffer, size, 1, file);
delete buffer;
break;
>
>

автор: psychomc (20.10.2009 в 12:08) письмо автору

не совсем понял как вызвать функцию из программы, точнее что в неё передать.

автор: psychomc (20.10.2009 в 12:12) письмо автору

а если такой вариант

можно ли считать файл с этой позиции и скажем запихнуть в перменную и записать с помощью fwrite с этой позиции??

автор: Волки (20.10.2009 в 12:39) письмо автору

> записать с помощью fwrite с этой позиции
с этой позиции нельзя, т.к. считав информацию про конкретный товар — указатель передвинулся, и надо вернуть назад на «размер товара»
а внутрь функции передается идентификатор удаляемой записи.
и кстати, у вас структура выравнена по границе 8 байт?

автор: psychomc (20.10.2009 в 12:46) письмо автору

>и кстати, у вас структура выравнена по границе 8 байт?
на этот вопрос у меня нет ответа т.к я не понял о чём Вы 🙁

указатель вот так получается возвратить обратно:

fseek(tf,-sizeof(prod),1);

так можно ли в таком случае записать переместив?

автор: Волки (20.10.2009 в 13:23) письмо автору

sizeof (prod) = 48 байт, что кратно 8 .
> так можно ли в таком случае записать переместив?
Да, думаю можно, пробовать надо, дебугером.

автор: psychomc (20.10.2009 в 13:40) письмо автору

никак не могу считать файл полностью с этой позиции

Удаления из файла данных (C++)

например я хочу удалить от туда запись Bobik или любую другую .

как можно сделать ? может сущетвует кой алгоритм удаления или надо мудрувать ?

15 ответов

29 октября 2007 года
256 / / 11.11.2005

Алгоритм зависит от того, по каким критериям ты будешь удалять запись: по номеру или по совпадению строк
Так что давай конкретнее

29 октября 2007 года
140 / / 11.09.2007

Алгоритм зависит от того, по каким критериям ты будешь удалять запись: по номеру или по совпадению строк
Так что давай конкретнее

впринцыпе все равно:p и вариант с удалением по сурагатному ключу или по совпаденю строк подходит

29 октября 2007 года
256 / / 11.11.2005
#include
#include
#include

using namespace std;

int main()
ifstream in («test.dat», ios::in);
ofstream out(«test.new», ios::out);
char buff[256];
int num,i;

Алгоритм по совпадению строк отличается парой-тройкой строк
30 октября 2007 года
140 / / 11.09.2007

max_dark спасибо за код.

я наверлно не правильно обяснил, по номеру строки не подходит.
лучше уж по совпадению строки:)))

30 октября 2007 года
1.0K / / 08.01.2007
30 октября 2007 года
140 / / 11.09.2007

m_Valery Спасибо 🙂

с кодом разобрался, только не смог асилить что значит это:

int _tmain(int argc, _TCHAR* argv[])

почему в вместо main() стоит _tmain и что за фишки: (int argc, _TCHAR* argv[])
30 октября 2007 года
1.0K / / 08.01.2007

Можешь вместо int _tmain(int argc, _TCHAR* argv[]) использовать
int main().int argc и _TCHAR* argv[]) — параметры командной строки. argc — количество параметров,argv — строки,представляющие отдельные значения. Смотри об этом подробнее в учебниках.В Visual Studio 2003,2005 используется int _tmain,в 6-й была просто main.

30 октября 2007 года
140 / / 11.09.2007

кстати а как вам такой вариант:

что на самом деле с файла ничего удалятся не будет
а только будут высавлястся статусы.

Tuzik <отступ>T
Shurik <отступ>T
Bobik <отступ>F
Sharik <отступ>T
Ivanov <отступ>F

там где F то значит что они «мертвые».
а там где T то значит что они «живые».

а в самой проге будет функция которая проверяет статусы и работает только с «живыми» пользователями . и функция по удалению, которая по сути статусы меняет на F

как такая идея, что скажите ?

это я делаю примочки к этому заданию:
http://forum.codenet.ru/showthread.php?t=42495

30 октября 2007 года
256 / / 11.11.2005
С такой структурой можно будет «воскрешать мертвецов» 😉
Если кого прибил по ошибке.
31 октября 2007 года
100 / / 04.09.2007

кстати а как вам такой вариант:

что на самом деле с файла ничего удалятся не будет
а только будут высавлястся статусы.

Tuzik <отступ>T
Shurik <отступ>T
Bobik <отступ>F
Sharik <отступ>T
Ivanov <отступ>F

там где F то значит что они «мертвые».
а там где T то значит что они «живые».

а в самой проге будет функция которая проверяет статусы и работает только с «живыми» пользователями . и функция по удалению, которая по сути статусы меняет на F

как такая идея, что скажите ?

main()
ofstream out(«dogs.dat»,ios::app);

char *name = new char[15];
char status;

в этом примере ты записываешь имя и статус, и читаешь имя и статус в отдельные переменные, и потом в цикле можешь сравнивать статус и вызывать функцию обработку с собаками

01 ноября 2007 года
49 / / 15.10.2006

Можно функции read и write использовать, они записывают в файл структуры в текстовом виде, и соответственно могут удалять структуры

06 декабря 2007 года
2 / / 06.12.2007

Помогите написать похожую прогу плз.
Программа должна удалять запись по совподению строк, но тока в файле в котором нужно удалить данные не один столбец, а 5.
Программа которая приведена в этой теме работает только если в файле один столбец.

07 декабря 2007 года
1.0K / / 08.01.2007

Помогите написать похожую прогу плз.
Программа должна удалять запись по совподению строк, но тока в файле в котором нужно удалить данные не один столбец, а 5.
Программа которая приведена в этой теме работает только если в файле один столбец.

Построчно считываем файл в вектор.Вводим слово.которое хотим удалить,удаляем его и перезаписываем файл.Например так.

Как удалить строки из файла

Чтобы удалить строки из файла отлично подойдет встроенное в командную строку Windows средство FINDSTR.

В нашем случае команда может выглядить так:

type file.txt | findstr /v ERROR | findstr /v REFERENCE 

Вывод в результате работы команды будет следующий:

C:\>type file.txt Good Line of data bad line of C:\Directory\ERROR\myFile.dll Another good line of data bad line: REFERENCE Good line C:\>type file.txt | findstr /v ERROR | findstr /v REFERENCE Good Line of data Another good line of data Good line

Использование sed чтобы удалить строки из файла

Если в системе установлен SED, можно выполнить следующую команду:

sed -e ‘/REFERENCE/d’ -e ‘/ERROR/d’ [FILENAME]

Здесь FILENAME — это имя файла, который содержит правильные и неправильные строки.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *