[Pascal] Требуется помощь. Изменение одного элемента в каждой записи всего файла.

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

Ответить
vlaad
Сообщения: 5
Зарегистрирован: 01 мар 2008, 21:52

Есть файл раннее созданный так же программкой на паскале, вот с такими элементами

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

type inf=record
               imya:string[15];
               familiya:string[15];
               dolzhnost:string[20];
               zarplata:real;
end;

var
     F: file of inf;
     Data: inf;
     .....
По заданию мне нужно увеличить зарплату на 5% и перезаписать файл с новыми значениями на месте "zarplata". Пробывал чего-то сделать, но получалось так, что вместо всех записей записывало одного человека (последнего из списка) и разные значения "зарплата" или записывало только значения зарплат и в итоге ничего не получилось.
Serge_Bliznykov
Сообщения: 375
Зарегистрирован: 31 авг 2007, 03:06

Ваша ошибка в том, что не рекомендуется и читать и писать в один и тот же файл.
А если так делать, то использовать совсем другие методы доступа к файлу!

Вот, пишу прямо на коленке (в броузере), поэтому ошибки подправить самостоятельно...

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


type inf=record
               imya:string[15];
               familiya:string[15];
               dolzhnost:string[20];
               zarplata:real;
end;

var
     F,F2: file of inf;
     Data: inf;
begin
  Assign(F, 'ФайлДанн.dat');
  Reset(F);
  Assign(F2, 'Temp$$$.dat'); {временный файл, куда будем писать новое}
  Rewrite(F2);
  while Not Eof(F) do begin
    Read(F,Data);
    Data.zarplata := Data.zarplata * 1.05;
    Write(F2,Data)
  end;
  close(F);
  Close(F2);
  Erase(F);
  Rename(F2,'ФайлДанн.dat');
end.
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Serge_Bliznykov писал(а):Ваша ошибка в том, что не рекомендуется и читать и писать в один и тот же файл.
Это почему же?
Открываешь бинарный (не текстовый) существующий файл через Reset, и можно и писать и читать.
Serge_Bliznykov
Сообщения: 375
Зарегистрирован: 31 авг 2007, 03:06

BBB, Вы правы. Почему то я решил, что для типизированных это не так.
тогда код можно переписать так:

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

type inf=record
               imya:string[15];
               familiya:string[15];
               dolzhnost:string[20];
               zarplata:real;
end;

var
     F : file of inf;
     Data: inf;
     i : integer;
begin
  Assign(F, 'ФайлДанн.dat');
  Reset(F);
  i := 0;
  while Not Eof(F) do begin
    Read(F,Data);
    Data.zarplata := Data.zarplata * 1.05;
    seek(F,i);
    inc(i);
    Write(F,Data)
  end;
  WriteLn('Обработали ',i:1,' записей.');
  close(F);
end.
Serge_Bliznykov
Сообщения: 375
Зарегистрирован: 31 авг 2007, 03:06

ещё добавлю в своё оправдание ;-)
К слову. я же написал - "не рекомендуется", а не "НЕЛЬЗЯ"... 8-))
и первый мой пример кода тоже был рабочий...
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Serge_Bliznykov,
В принципе, позицию для Seek можно получать, используя FilePos перед операцией чтения, а не считая счетчик i. Хотя ошибки в данном алгоритме нет.
Ответить