Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.05.2013, 21:12   #1
Cstln
 
Регистрация: 04.05.2013
Сообщений: 8
По умолчанию Вопрос по работе с файлами

Здравствуйте, уважаемые программисты!

У меня к вам следующий вопрос:

Есть 2 файла с записями (нечто вроде БД), и задача этой программы - добавить в первый файл (с указанной позиции pos) указанное число записей num из второго. Программу я написал, а вот результат нулевой - ничего не меняется. В чём ошибка?




Код:
program PROGR2;
uses crt;
const n=5;
type
    Record1=record
          name:string[20];
          year:integer;
          number:integer;
    end;
var
        f1,f2:file of Record1;
        i,j:integer;
        t,t2:Record1;
        
        pos:integer;
        num:integer;
        k:integer;
begin
clrscr;


assign(f1,'record1.txt');
assign(f2,'record2.txt');


clrscr;

reset(f1);
reset(f2);

writeln('Position');
readln(pos);
writeln('Number of records');
readln(num);


seek(f1,pos-1);

for i:=1 to num do
  begin
  seek(f1,pos-i);
  k:=0;
  read(f2,t);
  j:=pos-i;
    while k<>1 do
    begin
    seek(f1,j);
    if eof(f1) then
        begin
            inc(k);
            write(f1,t)
        end
      else
        begin
          read(f1,t2);
          seek(f1,j);
          write(f1,t);  
          t:=t2;
  
          inc(j)
        end
    end
  
  end;
close(f1);
close(f2);

readln;
clrscr;





readln;
end.

Последний раз редактировалось Cstln; 05.05.2013 в 19:14. Причина: исправил ошибку в коде
Cstln вне форума Ответить с цитированием
Старый 04.05.2013, 21:42   #2
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Первое, что обнаружил в Вашей программе - массу ненужных действий.
Вы бы хоть расставили комментарии - что пытаетесь сделать.
s-andriano вне форума Ответить с цитированием
Старый 04.05.2013, 22:01   #3
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,304
По умолчанию

Кроме того ...
Код:
reset(f1);
reset(f2);
Т.е. оба файла открываются на чтение и операции:
Код:
write(f1,t)
...
write(f1,t2);
не работают.
Для открытия файла в режиме записи следует использовать п/п:
Код:
rewrite(f);
Вроде так ...
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 04.05.2013, 22:35   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

ViktorR, для файла записей reset откроет и на чтение и на запись, насколько помню; а rewrite еще и сотрет содержимое файла.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 04.05.2013, 23:08   #5
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Цитата:
Сообщение от ViktorR Посмотреть сообщение
Вроде так ...
Нет.
"Так" - только для текстовых файлов. Для бинарных и типизированных reset по умолчанию открывает и на чтение, и на запись.
s-andriano вне форума Ответить с цитированием
Старый 04.05.2013, 23:25   #6
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,304
По умолчанию

Да. С замечанием согласен. Reset() - только чтение, если файл текстовый, а для типизированных можно писать.

Но вот еще одна вещь:
Код:
for i:=1 to num do
  begin
  seek(f1,pos-i); {откатываемся на одну позицию от текущей, затем на две позиции, но уже от той, которая была получена на предыдущем цикле и т.д.}
  k:=0;
  read(f2,t);
  j:=pos-i;
...
Возможно ошибка в коде тут?

Как-то так, ...
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 05.05.2013, 01:03   #7
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Цитата:
Сообщение от ViktorR Посмотреть сообщение
Да. С замечанием согласен. Reset() - только чтение, если файл текстовый, а для типизированных можно писать.

Но вот еще одна вещь:
Код:
for i:=1 to num do
  begin
  seek(f1,pos-i); {откатываемся на одну позицию от текущей, затем на две позиции, но уже от той, которая была получена на предыдущем цикле и т.д.}
  k:=0;
  read(f2,t);
  j:=pos-i;
...
Возможно ошибка в коде тут?

Как-то так, ...
Здесь ошибки быть не может.
Это как раз одна из тех многочисленных операций, которые совершенно лишние, т.к. ни на что не влияют.
s-andriano вне форума Ответить с цитированием
Старый 05.05.2013, 19:12   #8
Cstln
 
Регистрация: 04.05.2013
Сообщений: 8
По умолчанию

Простите, я в программировании не очень силён, но ненужных действий не вижу.
Я думал так:
При каждом действии над найлом у него сдвигается позиция на +1. Но чтобы и писать, и читать, приходится делать сдвиги назад.

Код:
for i:=1 to num do
  begin
  seek(f1,pos-i); 
  k:=0;
  read(f2,t); {Считываю из 2 файла запись}
  j:=pos-i;
    while k<>1 do
    begin
    seek(f1,j);
    if eof(f1) then {Если дошёл до конца файла, то выхожу из цикла, записав оставшуюся в памяти последнюю запись}
        begin
            inc(k);
            write(f1,t)
        end
      else  {Иначе (в общем случае): }
        begin
          read(f1,t2); {Считываю в "буфер" запись из f1}
          seek(f1,j);
           write(f1,t);   {Записываю на её место другую запись}
          t:=t2; {По прохождении всех действий оставшуюся запись перемещаю опять в t2}
          inc(j)
        end
    end
Получается просто нечто вроде алгоритма сортировки применительно к файлам:
1) Забираю из f2 запись в перменную t
2) Циклом while устраиваю перебор в f1: "смещаю" записи на 1 элемент при помощи t и t2
т .е. в нужное место вставляется элемент, а все послестоящие записи смещаются на 1 позицию

и так повторяется num раз

P.S.:я подправил в коде 1 ошибку (поменял местами 2 команды в цикле)
Cstln вне форума Ответить с цитированием
Старый 05.05.2013, 21:31   #9
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Цитата:
Сообщение от Cstln Посмотреть сообщение
Простите, я в программировании не очень силён, но ненужных действий не вижу.
Код:
begin
clrscr; // не знаю, зачем, но здесь мы чистим экран

assign(f1,'record1.txt');
assign(f2,'record2.txt');

clrscr; // здесь чистим повторно - зачем?

reset(f1);
reset(f2);

writeln('Position');
readln(pos);
writeln('Number of records');
readln(num);


seek(f1,pos-1); // строка (1) - позиционируем в файле f1

for i:=1 to num do
  begin
  seek(f1,pos-i); // строка (2) - отменяет действие (1) - т.е. (1) не нужна
  k:=0;
  read(f2,t);
  j:=pos-i;
    while k<>1 do
    begin
    seek(f1,j); // строка (3) - отменяет действие (2) - т.е. (2) тоже не нужна
Это я к чему?
Я не знаю, что Вы хотите делать, возможно, Вы что-то пропустили, а возможно, написали лишнее, поэтому и прошу прояснить.
Цитата:
Я думал так:
При каждом действии над найлом у него сдвигается позиция на +1. Но чтобы и писать, и читать, приходится делать сдвиги назад.

Получается просто нечто вроде алгоритма сортировки применительно к файлам:
1) Забираю из f2 запись в перменную t
2) Циклом while устраиваю перебор в f1: "смещаю" записи на 1 элемент при помощи t и t2
т .е. в нужное место вставляется элемент, а все послестоящие записи смещаются на 1 позицию

и так повторяется num раз

P.S.:я подправил в коде 1 ошибку (поменял местами 2 команды в цикле)
Алгоритм, честно говоря, слишком сложный и очень неоптимальный - мы можем сотни раз переписывать что-то с места на место.
Воспользуйтесь третьим файлом и алгоритм существенно упростится и, главное, будет работать оптимально по скорости и количеству выполняемых операций.
Могу предложить два варианта (оба используют третий файл):

1. Создается новый файл, в который сначала переписывается содержимое первого файла до позиции вставки, затем - содержимое второго файла и, наконец, "хвост" первого файла. При необходимости первый файл уничтожается, а новый - переименовывается.

2. Первый файл позиционируется сразу на нужную позицию, во временный (третий) файл переписывается весь "хвост" первого файла, первый файл вновь позиционируется на ту же нужную позицию, после чего в него дописываются содержимое сначала второго, а потом - третьего файла. Временный файл уничтожается.
s-andriano вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по работе с файлами (Delphi) BigDa Общие вопросы Delphi 6 25.04.2012 21:01
Задание по работе с файлами (C) Jersey Помощь студентам 1 28.12.2011 09:59
Вопрос по работе с файлами Елжан Помощь студентам 0 01.12.2011 19:23
Вопросы по работе с файлами С++ Alex456 Общие вопросы C/C++ 4 14.06.2011 22:27
Интересный вопрос по работе с файлами в C++ FastDead Общие вопросы C/C++ 8 25.12.2009 23:13