Помощь - Поиск - Пользователи - Календарь
Полная версия: удаление в типиз. типах
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
kr3v3tkus
задача:
1 Открыть файл
2 Добавить запись
3 Изменить запись по номеру
4 Удалить запись по номеру
5 Распечатать построчно
6 Выйти

Проблема с 4 пунктом. Препод сказал сделать так - узнать номер строки, создать новый файл и перенести туда все строки кроме этой, потом - переименовать новый файл в старый. Подскажите плз как сделать, а уж с 5 и 6( smile.gif ) я сам разберусь yes2.gif

program lol;
uses crt;
label metka1, metka2;
type Pprice=record
Pname:string[20];
Pvalue:real;
end;
var price:file of Pprice;
p:pprice;
i,n,z,x:integer;
procedure vivod;
begin
reset(price);
while not eof(price) do
begin
read(price,p);
write(p.pname:10);
writeln(p.pvalue:10:2);
writeln;
end;
close(price);
end;

begin
clrscr;
begin {' otkritie '}
assign(price,'C:\price.dat');
write('noviy file - 0, redakt - 1 ');
readln(i);
if i=0 then rewrite(price) else reset(price);
end;

begin {' dobavlenie '}
write('dobavit? da - 1, net - 0 ');
readln(n);
if n=1 then
begin
metka1:
seek(price,filesize(price));
write('vvedite na3vanie tovara ');
read(p.pname);
write('vvedite na3vanie ceni ');
read(p.pvalue);
write(price,p);
write('dobavit? da - 1, net - 0 ');
readln(n);
if n=1 then goto metka1;
end;
close(price);
end;

vivod;

begin {' i3menenie '}
reset(price);
metka2:
write('vvedite nomer stroki dlia i3meneniya ');
readln(i);
seek(price,i-1);
write('vvedite na3vanie tovara ');
read(p.pname);
write('vvedite na3vanie ceni ');
read(p.pvalue);
write(price,p);
write('eshe redaktirovat? da - 1, net - 0 ');
readln(n);
if n=1 then goto metka2;
close(price);
end;

vivod;

begin {' ydalenie '}
write('vvedite nomer stroki dlia ydaleniya ');
readln(i);
??? sad.gif
end;

readln;
end.
volvo
Цитата
Препод сказал сделать так - узнать номер строки, создать новый файл и перенести туда все строки кроме этой
Бред... Нет в типизированном файле такого понятия, как строка, можешь своему преподу прямо так и сказать...

Все, что могу предложить:
const
old_name = 'old.dat';
new_name = 'new.dat';

...
{ здесь - создаешь новый файл new_file }
...
while not eof(old_file) do begin
read(old_file, r); { ичтаем запись }
if { какое-то условие, при выполнении которого запись НУЖНО переносить }
then write(new_file, r);
end;

close(new_file); close(old_file);
erase(old_file);
rename(new_file, old_name);

Учти, что после этого надо будет заново делать Assign для old_file, если захочешь с ним работать...
kr3v3tkus
2 volvo:
пардон, мой косяк спешил и описа'лся , я имелл ввиду конкретную запись а не строку smile.gif
только я не совсем понял в этом коде

Цитата
read(old_file, r);
if { какое-то условие}
then write(new_file, r);


он копирует из старого файла запись в новый, и, если нам, например, нужно убрать 3ю запись, то мы в if пишем условие, чтоб 3я не копировалась? (пардон ещё раз, не оч с темой разобрался)
volvo
Цитата
он копирует из старого файла запись в новый, и, если нам, например, нужно убрать 3ю запись, то мы в if пишем условие, чтоб 3я не копировалась?
yes2.gif Именно так и пишешь:
  if filepos(old_file) <> 3 
then write(new_file, r);
Третья запись (отсчет начинается с 1-цы) перенесена в новый файл не будет...
kr3v3tkus
Пасибоньки smile.gif в который раз... smile.gif
мисс_граффити
основа такая же, но маленькое дополнение внесу.

можно в саму запись добавить одно поле логического типа. везде написать true.
и когда мы знаем, какие записи удалить - проставить в них false.
это позволит за один проход удалять сколько угодно записей.
klem4
И зачем хранить совершенно лишнюю и не нужную информацию ? Если может потребоваться за один раз удалить только одну запись ? (это достаточно четко понятно по заданию)

Единственное что могу предложить для удобства работы с базой (чтобы постоянно не обращаться к файлу) в начале работы сохранть записи в массиве и работать с ним до завершения программы, преде самым ее концом перезаписав элементы массива в файл.
volvo
Цитата(мисс_граффити @ 15.03.2006 8:22) *
можно в саму запись добавить одно поле логического типа. везде написать true.
и когда мы знаем, какие записи удалить - проставить в них false.
это позволит за один проход удалять сколько угодно записей.

Логическая неувязочка... no1.gif Если мы знаем, когда ставить True, а когда False, то что нам мешает подставить условие, это определяющее, в предложенный мной алгоритм? Функциональность - та же, лишние данные не используются и не хранятся в базе...
мисс_граффити
всегда надо удалять только одну запись?
volvo
мисс_граффити, давай ты будешь ВНИМАТЕЛЬНО читать то, что здесь пишут? mad.gif КАКАЯ разница, объясни мне, ламеру, будешь ты хранить поле, которое может содержать True/False или напишешь функцию, которая будет сразу определять, удалять запись или нет? ОТКУДА True/False браться -то будет ??? С неба? С потолка? Его же найти еще надо !!!

И какая разница, сколько записей удалять?
kr3v3tkus
я конечно извиняюс за свою тупость, но никак не могу исправить ошибку. volvo вот вы писали дат файлы в константах, тогда их можно в варе не использовать? вобщем я описал вот так
Код
type Pprice=record
             Pname:string[20];
             Pvalue:real;
             end;
var price:file of Pprice;
      newprice:file of Pprice;
      p:pprice;

и естественно ничего не пашет dry.gif :
Код
begin  {' otkritie '}
  assign(newprice,'C:\newprice.dat');
  rewrite(newprice);
  assign(price,'C:\price.dat');
  write('noviy file - 0, redakt - 1  ');
  readln(i);
  if i=0 then rewrite(price) else reset(price);
end;

...

begin  {' ydalenie '}
  write('ydaliaem 3apis? da - 1, net - 0  ');
  readln(n);
  if n=1 then
  begin
    metka3:
    write('vvedite nomer stroki dlia ydaleniya  ');
    readln(i);
    while not eof(price) do
      begin
      read(price,p);
      if filepos(price)<>i then write(newprice,p);
      end;
  close(newprice);
  close(price);
  erase(price);
  rename(newprice,price);
  assign(price,'C:\price.dat');
  reset(price);
  write('eshe ydaliaem? da - 1, net - 0  ');
  readln(n);
  if n=1 then goto metka3;
  end;
end;


ошибку пишет вот тут - rename(newprice,price) 67ю
volvo
Я не говорил тебе переименовывать так:
var
price:file of Pprice;
newprice:file of Pprice;
...
rename(newprice,price);
Это не будет работать... Читай внимательно:
Цитата
const
old_name = 'old.dat'; { Это - СТРОКА, имя файла, а не файл !!! }
new_name = 'new.dat';
...
rename(new_file, old_name);
kr3v3tkus
вроде понял, это просто строка, в которую мы переименовываем, но всё равно теперь при ренейме пишет, что доступ к файлу запрещён mega_chok.gif
чегото я запутался wacko.gif shok.gif
volvo
Не знаю, что у тебя происходит: только что прогнал программу, все нормально удаляется... Ты этот файл, newprice.dat, случайно, не пытался просмотреть как-нибудь? Может, он где-то открыт у тебя, кроме твоей программы? Потому, что ЭТА ошибка - никак с твоей программой не связана. Это ошибка ОС "Нет доступа".

Попробуй удалить этот файл НЕ через программу. Интересно, получится ли?
kr3v3tkus
blink.gif офигеть, а у меня не прёт cray.gif
системой файл не занят, я нигде не открывал его, удаляться - нормально удаляется. Вот типу дал задачку эту надо у него спросить
оффтоп: и ваще енто рок наверна, ща вот в инст приехал, а там с уроков отпросились. А инст на другом краю города, дожд идёт dry.gif . Это походу вселенская чернота какая то molnia.gif
kr3v3tkus
Блин, вобщем сдал я прорамку эту(тока 2 чела удаление наметали(включая меня lol.gif ), и то так не у кого и не заработало, поэтому препод сказал без удаления мутить), а она и там не работает, вернее работает и даже удаляет 1 раз, но во второй упрямицца и не хочет dry.gif вобщем препод сказал типа в отладке надо смотреть, потому что файл занят после 1го удаления, а я не умею unsure.gif .Впринципе то это уже необязательно, но разобраться хочецца, может кто подскажет в чём дело?
vladivarov
Да мне кажется, что любой ответ будет являться субъективным. Сколько людей - столько мнений.
На вкус и цвет ...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.