Проблема с файлами

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
somebody_now
Сообщения: 35
Зарегистрирован: 02 окт 2007, 14:43

Задание в следующем:
Разработать программу, которая заносит во внешний файл записи упорядоченного списка, и программу, которая добавляет в сформированный внешний файл данные об М товарах, при этом, не нарушая упорядоченности исходного файла. Если среди добавляемых товаров встречается товар, сведения о котором в файле уже есть, то необходимо их обновить, т. е. старую запись исключить.
(Упорядочены товары по невозрастанию [убыванию] года выпуска)
------------
проблемы во второй..если смотреть только добавление записей и проверку на идентичность с ранее написанным то проблем не возникает. корректно удаляется старая запись и в конец файла под нужным номером добавляется новая. а вот если брать весь алгоритм [с сортировкой вместе] то здесь корректного выполнения не получается..
если запсиь какого-то товара не свопадает с ранее написанной,то она как надо встанет на своё место при сортировке по году выпуска товара, но если старую запись надо удалить,она конечно будет удалена, но встанет ровно на то мевсто где стояла старая (с тем же названием). примечательно,что запуская прогу во второй раз, всё отсортируется нормально,включая вновь забитые записи. Вопрос: в чём ошибка?? в коде думаю не стоит приводить заполнение файла исходными данными, поэтому собсно часть 2:

Код: Выделить всё

program ch2;
const n=11;
      m=3;
type tovar=record
      nazvanie:string[20];
      cena:500..50000;
      god:1990..2007;
      kolvo:byte;
      end;
var  s,s1,p,p1,p2,p3,p4,z1,z2,z3:tovar;
f:file of tovar;
y,h,i,c,j,k,l,z,q,r:integer;
begin
assign(f,'C:/tovars.dat');
reset(f);
while not eof(f) do begin
read(f,s1);
with s1 do
writeln(nazvanie:20,' ':5,cena:5,' ':5,god:4,' ':5,kolvo);
end;
close(f);


writeln('dobavlyaem ',m,' tovarov:');
reset(f);
seek(f,filesize(f));
for i:=1 to m do begin
    with s1 do begin
    writeln('vvedite nazvanie tovara');
    readln(nazvanie);
    writeln('vvedite stoimost tovara');
    readln(cena);
    writeln('vvedite god vipuska tovara');
    readln(god);
    writeln('vvedite kol-vo tovara');
    readln(kolvo);
    end;
k:=0;
z:=filesize(f)-1;
while k<=z do begin
seek(f,k);
h:=filepos(f);
read(f,p);
          if (p.nazvanie=s1.nazvanie) then begin
          for j:=h to z-1 do begin
          seek(f,j+1);
          read(f,p);
          seek(f,j);
          write(f,p);
          end;
          seek(f,z);
          truncate(f);
          z:=z-1;
          end else k:=k+1;
end;
write(f,s1);
for q:=0 to filesize(f)-1 do
    for r:=q to filesize(f)-2 do begin
    seek(f,r); read(f,z1);
    seek(f,r+1); read(f,z2);
    If (z1.god<z2.god) then begin
    seek(f,r);
    write(f,z2);
    seek(f,r+1);
    write(f,z1);
    end;
    end;
end;
close(f);

reset(f);
while not eof(f) do begin
read(f,s1);
with s1 do
writeln(nazvanie:20,' ':5,cena:5,' ':5,god:4,' ':5,kolvo);
end;
close(f);
readln;
end.
somebody_now
Сообщения: 35
Зарегистрирован: 02 окт 2007, 14:43

Неужели ни у кого нет даже предположений по теме? Время поджимает(
Аватара пользователя
annihilator
Сообщения: 35
Зарегистрирован: 27 ноя 2007, 00:22

короче смотри. Создай в программе массив записей (array[] of tovar) который бы вместил в себя весь файл. Грузи данные в него, редактируй и сортируй как хочешь, а потом rewrite(f) и лей массив в файл. По моему самое рульное решение, если по быстрому и без гемора.
Сам когда редактировал базы данных (надо было делать замену в строках текстового файла, большого, чтобы в память не влез =)) создавал tmp файл в который лил отредактированное, а потом сносил исходный файл и менял расширение tmpшника
Вот представьте себе: чистое поле - ни кустика, ни деревца, и вдруг из-за угла выезжает танк!
Аватара пользователя
annihilator
Сообщения: 35
Зарегистрирован: 27 ноя 2007, 00:22

постскриптум - для сортировки лучше всего использовать метод пузырька, используя промежуточную переменную типа tovar
Вот представьте себе: чистое поле - ни кустика, ни деревца, и вдруг из-за угла выезжает танк!
Аватара пользователя
annihilator
Сообщения: 35
Зарегистрирован: 27 ноя 2007, 00:22

извини что не сказал ничего полезного по поводу твоего исходника - просто не могу его понять, честно говоря... мозги после ночи не работают... а того что я предложил должно хватить... да и большинство программ для обработки баз данных выгружают базу в память, и потом уже просто перезаписывают файл базы...
Вот представьте себе: чистое поле - ни кустика, ни деревца, и вдруг из-за угла выезжает танк!
somebody_now
Сообщения: 35
Зарегистрирован: 02 окт 2007, 14:43

annihilator, спасибо,опробую,сдавать завтра,поэтому собсно и спрашивал)
Аватара пользователя
annihilator
Сообщения: 35
Зарегистрирован: 27 ноя 2007, 00:22

на крайняк если не получится... подумал в общем.... если у тебя не хватит памяти для массива, то можно создавать tmp файл, дописывать новые записи в конец исходного файла и считывать последовательно данные:
reset(f);
read(f,sl);
var0:=sl;
repeat
read(f,sl);
if sl.god > var0.god then {здесь вставь цикл сверки - не занесён ли элемент в временный файл} var0:=sl;
until eof(f);
write(tmpfile,var0);
так ты находишь наибольшие элементы (приведена начинка цикла поиска).
Главное - если будешь так делать, не забудь создать массив, в который будешь заносить идентификаторы уже записанных в tmpfile. Тогда сначала в файл запишутся товары наиболее позднего года выпуска, потом по мере заполнения массива будут заноситься всё более старые. Без дубликации.
Вот представьте себе: чистое поле - ни кустика, ни деревца, и вдруг из-за угла выезжает танк!
Ответить