Помощь - Поиск - Пользователи - Календарь
Полная версия: База данных с помощью записей
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
hemm
Суть такова: написал базу данных, но не могу никак сообразить, возможно ли редактировать в такой БД запись отдельно. Как мне выделить/вычленить любую по желанию запись и, например, удалить только ее или отредактировать? Или лучше использовать для такой БД двумерные массивы?


*Тупанул при написании. Для запуска файла надо в том же каталоге создать файл "database" и указать его имя при запросе в программе.




program students;

uses crt,dos;

label ChangeFile;

type spisok = record
    nomer: string[6]; // Порядковый номер
    zach: string[7]; // Номер зачетной книжки
    fam: string[20]; // Фамилия
    imya: string[20]; // Имя
    otch: string[20];  //Отчество
    gruppa: string[8]; //Номер группы
end;

StudentDataBase = file of spisok;

var a: StudentDataBase;
  i, z: integer;
  s: real;
  c:char;
  q:boolean;
  DataBase: string;
  k:byte;

  p:string;
  ss:string;

{-------------------------------------------------> INPUT}
procedure new(var a: StudentDataBase);
   var j: integer;  zk: spisok;
begin
  reset(a);
   seek(a, filesize(a));
    repeat
    begin

     with zk do begin

      writeln;

      write('#................: ');
      readln(nomer);

      write('Зачетная книжка..: ');
      readln(zach);

      write('Фамилия..........: ');
      readln(fam);

      write('Имя..............: ');
      readln(imya);

      write('Отчество.........: ');
      Readln(otch);

      write('Группа...........: ');
      readln(gruppa);

      writeln;

      write(a, zk);

      writeln;
      writeln('Продолжить запись? Да: 1 Нет: 0');

      readln(j);
    end;
end;
until j =0;

close(a);
end;
{-----------------------------------------------> // INPUT}






{-------------------------------------------------> OUTPUT}
procedure output(var a: StudentDataBase);
   var i: integer; zk: spisok;
begin
  with zk do begin
  clrscr;
  reset(a);
  writeln;
  writeln('                            База данных "Студенты"           ');
  writeln;
  writeln(& #39;============================================================================
===');
  writeln('   №  | з/книжка |     Фамилия     |     Имя     |     Отчество     |  Группа  ');
  writeln(& #39;============================================================================
===');

  while not eof(a) do

  begin
  read(a, zk);
    write(nomer:6);
    write('|', zach: 10);
    write('|', fam: 17);
    write('|', imya: 13);
    write('|', otch: 18);
    write('|', gruppa: 8);
    writeln;
    writeln('-------------------------------------------------------------------------------');

end;
writeln;
writeln('                   Нажмите клавишу Enter для перехода в меню...');
  close(a);
end;

  readln;
end;
{-----------------------------------------------> // OUTPUT}




{------------------------------------------> FIND}

procedure find(var a: StudentDataBase);
var i: integer;
  zk: spisok;
  student: string;
 begin
   clrscr;
   reset(a);
      write('Введите данные для поиска: ');
      readln(student);
      writeln;
      writeln('                            База данных "Студенты"           ');
      writeln;
      writeln(& #39;============================================================================
===');
      writeln('   №  | з/книжка |     Фамилия     |     Имя     |     Отчество     |  Группа  ');
      writeln(& #39;============================================================================
===');


while not eof(a) do
   begin
    with zk do begin
    read(a, zk);
     if (zach = student) or (fam=student) or (imya=student) or (otch=student) or (gruppa=student) then
      begin
        write(nomer:6);
        write('|', zach: 10);
        write('|', fam: 17);
        write('|', imya: 13);
        write('|', otch: 18);
        write('|', gruppa: 8);
        writeln;
        writeln('-------------------------------------------------------------------------------');
      end;
   end;
end;
  close(a);
  writeln;
  writeln('                   Нажмите клавишу Enter для перехода в меню...');
  readln;
end;

{------------------------------------------> // FIND}






begin
   changefile:


{------------------------------------------> LOADING}

clrscr;
 write('Укажите имя загружаемой базы: ');
 readln(DataBase);
 repeat
 clrscr;
 assign(a, DataBase);
{------------------------------------------> // LOADING} // временно отключил






{-------> MENU}

    write('Disk Size: ', DiskSize(0) div 1024 div 1024, ' Мбайт');
    writeln;
    write('Current File: ', DataBase);
    writeln;
    writeln('Menu: ');
    writeln;
    writeln('1: New Record(-s)');
    writeln('2: Output Record(-s)');
    writeln('3: Find Record(-s)');
    writeln('4: Change File | отключил');
    writeln('5: Exit');
    writeln('6: Delete File');
    writeln('7: Add Record(-s) | не работает');
    writeln('8: Delete Record(-s) | не работает');
    writeln('9: Current Record: | не работает');
    readln(z);

   case z of
     1: new(a);
     2: output(a);
     3: find(a);
     4: goto changefile;
     5: q:=true;
     6: begin
erase(a);
writeln;
write('File ', Database, ' was deleted');
readln;
end;
   end;
   until q;
end.
 
Lapp
Цитата(hemm @ 24.06.2011 1:34) *
Суть такова: написал базу данных, но не могу никак сообразить, возможно ли редактировать в такой БД запись отдельно. Как мне выделить/вычленить любую по желанию запись и, например, удалить только ее или отредактировать? Или лучше использовать для такой БД двумерные массивы?

Односложный ответ на твой вопрос такой: да, конечно - впрограммировании можно ВСЕ. Но односложным тут не обойтись, боюсь )).

Редактировать запись очень просто. Открываешь reset'ом, подходишь к началу нужной записи, читаешь, редактируешь, возвращаешься на одну запись в файле и пишешь ее - все, только не забыть закрыть.

Удалять несколько сложнее, если сохранять порядок следования записей в файле. Нужно

найти запись, встать за ней, 
repeat
   прочитать, вернуться на две записи, записать, пропустить одну запись
until eof(f)


Но только это делать необязательно. Хранить записи можно в произвольном порядке (ее номер все равно сохраняется в поле nomer). Если тебе надо стереть запись - просто перемещаешь последнюю на ее место и файл обрезаешь на одну запись. Номера записей при этом будут непоследовательными. Например, из ряда 1 2 3 4 5 стираешь запись 3, остаются записи 1 2 4 5, которые реально в файле следуют в таком порядке: 1 2 5 4. Когда ты добавишь еще одну запись, будет 1 2 5 4 6. А поиск записи с нужным номером можно проводить либо последовательно, либо создать карту записей. Ее можно сделать либо отдельным файлом (что не очень надежно), либо отвести под нее пространство в начале файла.

Но, помимо этого, я бы советовал тебе продумать структуру программы. Такие безобразия, как метки - это колесо машины, починенное скотчем.. smile.gif
Остальные замечания высказывать?
hemm
с радостью выслушаю все замечания.

чем посоветуете заменить метку? repeat...until?
и можно какой-нибудь пример карты записей. не очень понимаю о чем речь.
спасибо.
IUnknown
Цитата
чем посоветуете заменить метку? repeat...until?
Хотя бы... Тебе надо будет обернуть все, начиная от метки до конца твоего теперешнего Repeat/Until еще одним циклом, и при выборе "4: Change File" просто делать break. Из внутреннего цикла программа тут же выйдет, и перейдет к началу внешнего, то есть, туда, где стояла метка. Условие выхода из внешнего цикла остается прежним, "until q", так что в случае, когда пользователь захочет выйти из программы - выйдешь сразу из обоих циклов.

Что касается
Цитата
if (zach = student) or (fam=student) or (imya=student) or (otch=student) or (gruppa=student) then
- я бы так не делал. Мало ли, фамилии и отчества могут совпадать, всякое бывает. Лучше пусть пользователь введет еще один признак (где именно искать), и сравнивать именно по какому-то конкретному полю записи. Ну, про использование процедур вместо дублирования кода (вывод "шапки", и вывод одной записи на экран) тоже не стоит забывать...
Lapp
Цитата(hemm @ 24.06.2011 11:41) *
с радостью выслушаю все замечания.
Тогда еще раз повторю: продумай функционал и структуру. Нарисуй блок-схему.
Ну и переименуй процедуру new - нехорошо подменять системные процедуры..

Цитата
чем посоветуете заменить метку? repeat...until?
IUnknown сказал уже, я только добавлю: если появляется желание воспользоваться goto - значит, программа организована неправильно. Воспринимай это как признак, что что-то не так.

Цитата
и можно какой-нибудь пример карты записей. не очень понимаю о чем речь.
Так я уже привел же - вот те циферки и есть карта.. Просто массив целых - заполняешь его номерами записей, и при стирании/добавлении корректируешь. Инициализируй его нулями, и при стирании тоже заменяй последнюю (перемещенную на место стертой) нулем. Сначала попробуй ее писать в отдельный файл - это проще. А потом покажем, как в тот же.
Какой у тебя компилятор? Это тут может быть важно.

Но вообще - может, лучше сначала без карты, просто поиск по полю number. А потом можно и карту сделать, если останется желание.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.