Guest User

Untitled

a guest
Jan 24th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 19.46 KB | None | 0 0
  1. uses CRT;
  2.  
  3. const  Parts: array [1..6] of string = ('Австралия и Океания', 'Азия', 'Америка', 'Антарктида', 'Африка', 'Европа');
  4.  
  5. Type Data = Record
  6.                Country:string;
  7.                Part:integer;
  8.                Capital:string;
  9.              End;
  10. NodePtr = ^Node;    {указатель на элемент списка}
  11. Node = record   {элемент списка}
  12.     D: Data;    {данные}
  13.     Prev,Next: NodePtr; {указатели на предыдущий и следующий элементы списка (двусвязный список)}
  14.     end;
  15.  
  16. Predicate = function(var D:Data):boolean;
  17.  
  18. var
  19.   Mode:byte;
  20.   First, Current, Last:NodePtr; {указатели на первый, текущий и последний элементы списка}
  21.   F:file of Data;
  22.   i:Data;
  23.   Mode1Part: integer;
  24.   Mode2Country: string;
  25.  
  26. {----------------------------------------------------------------------------}
  27. procedure PushBack(var D:Data);  {Занесение данных в конец списка}
  28. begin
  29.   if SizeOf(Node) <= MaxAvail then {Проверка на размер доступной памяти. SizeOf(X) - размер переменных типа X в байтах, MaxAvail - размер наибольшего непрерывного участка памяти}
  30.     begin
  31.        if First = Nil then {Если создается 1-й элемент списка}
  32.        begin
  33.          New(First);  {выделяем память}
  34.          First^.D := D; {присваиваем данные}
  35.          First^.Next:=Nil; {в списке 1 элемент => связей нет}
  36.          First^.Prev:=Nil;
  37.          Last := First; {указатель на 1-й элемент = указателю на последний}
  38.        end
  39.        else
  40.        begin {Добавление данных в конец списка (1-й элемент уже создан)}
  41.          new(Last^.Next); {выделяем память (тут же происходит связывание последнего элемента с создаваемым)}
  42.          Last^.Next^.Prev := Last; {связываем только что созданный элемент с предыдущим}
  43.          Last := Last^.Next; {передвигаем указатель на созданный элемент}
  44.          Last^.D := D; {присваиваем данные}
  45.          Last^.Next := Nil; {Следующего элемента нет}
  46.        end;
  47.   end
  48.   else {если недостаточно памяти, то}
  49.   begin
  50.     Writeln('Недостаточно памяти'); {выведем сообщение}
  51.     readkey;
  52.     halt; {и завершим программу}
  53.   end;
  54. end;
  55. {----------------------------------------------------------------------------}
  56. procedure ListDelete(N:NodePtr); {удаление из списка элемента, на который указывает N}
  57. begin
  58.     if N = First then {если удаляется 1-й элемент}
  59.     begin
  60.       if First^.Next <> Nil then {в списке больше 1 элемента}
  61.       begin
  62.          First := First^.Next; {передвинем указатель First на следующий элемент}
  63.          First^.Prev := Nil;   {Предыдущей элемент удален}
  64.       end
  65.       else {если в списке всего 1 элемент}
  66.       begin
  67.          First := Nil; {Нет элементов - нет указателей,}
  68.          Last  := Nil; {такие дела}
  69.       end;
  70.       Current := First; {Текущий элемент - первый}
  71.       Dispose(N); {Освобождаем память из под удаленного элемента}
  72.       exit;     {Выход из процедуры}
  73.     end;
  74.     if N = Last then {Удаление последнего элемента}
  75.     begin
  76.       Last := Last^.Prev; {переместим указатель Last на предыдущий элемент}
  77.       Last^.Next := Nil;  {Следующий элемент удален}
  78.       Current := Last;    {Текущий элемент - последний}
  79.       Dispose(N);   {Освобождаем память из под удаленного элемента}
  80.       exit;     {Выход из процедуры}
  81.     end;
  82.         {Удаление элементов, которые не являются ни первым, ни последним}
  83.       N^.Prev^.Next := N^.Next; {Связываем элемент, предшествующий элементу N, со следущим за N элементом}
  84.       N^.Next^.Prev := N^.Prev; {{Связываем элемент, следущий за N, с предшествующим N элементом}
  85.       Current := N^.Prev; {Текущий элемент - элемент, предшествующий элементу N}
  86.       Dispose(N);   {Освобождаем память из под удаленного элемента}
  87.  
  88. end;
  89. {----------------------------------------------------------------------------}
  90. function Menu:integer; {см. Lab5}
  91. procedure Select(SM,N:integer);
  92. begin
  93.   if N in [1..3] then
  94.   begin
  95.     GotoXY(2, SM + 1);
  96.     write(' ');
  97.     GotoXY(2, N + 1);
  98.     write('*');
  99.   end
  100. end;
  101.  
  102. var
  103.   mode: integer;
  104.   c: char;
  105.   ext:boolean;
  106. begin
  107.   clrscr;
  108.   repeat
  109.     writeln('Выберите Режим');
  110.     writeln('[*] Ввод данных');
  111.     writeln('[ ] Просмотр и редактирование');
  112.     writeln('[ ] Выход');
  113.  
  114.     mode := 1;
  115.     repeat
  116.       c := readkey;
  117.       if c in ['1'..'3'] then
  118.       begin
  119.          Select(mode, ord(c) - ord('0'));
  120.          mode := ord(C) - ord('0');
  121.       end;
  122.       if c = #0 then ext := true;
  123.       if (c in [#72,#80]) and ext then
  124.       begin
  125.         if (c = #72) and (mode > 1) then
  126.         begin
  127.            Select(mode, mode - 1);
  128.            dec(mode);
  129.         end;
  130.         if (c = #80) and (mode < 3) then
  131.         begin
  132.            Select(mode, mode + 1 );
  133.            inc(mode);
  134.         end;
  135.         ext := false;
  136.       end;
  137.     until c = #13;
  138.   until c = #13;
  139.   menu := mode;
  140. end;
  141.  
  142. {-----------------------------------------------------------------------------}
  143. procedure ClrLine(Y,X:integer);{см. Lab5}
  144. var
  145.   i:integer;
  146. begin
  147.   GotoXY(X,Y);
  148.   ClrEOL;
  149. end;
  150. {---------------------------------------------------------------------------}
  151. procedure Message(Y:word; s:string);{см. Lab5}
  152. var
  153. X_,Y_:integer;
  154. begin
  155.   X_ := WhereX;
  156.   Y_ := WhereY;
  157.   ClrLine(Y,1);
  158.   write(s);
  159.   GotoXY(X_,Y_);
  160. end;
  161. {-----------------------------------------------------------------------------}
  162. function ReadStr(Y:integer; var S:string; var Quit:boolean):char;{см. Lab5}
  163. var
  164.   c:char;
  165.   i:integer;
  166.   ext:boolean;
  167. begin
  168.   ClrLine(Y, 14);
  169.   i := Length(S);
  170.  
  171.   write(S);
  172.   ext := false;
  173.   Quit := false;
  174.   repeat
  175.     c := readkey;
  176.     if c = #27 then
  177.     begin
  178.       Quit := true;
  179.       exit;
  180.     end;
  181.     if (c = #8) and (i > 0) then
  182.     begin
  183.       GotoXY(WhereX-1, WhereY);
  184.       write(' ');
  185.       GotoXY(WhereX-1, WhereY);
  186.       delete(S, i, 1);
  187.       dec(i);
  188.     end;
  189.     if c = #0 then ext := true;
  190.     if (c in ['a'..'z', 'A'..'Z', 'а'..'я', 'А'..'Я','-']) and (i<80-14) and not ext then
  191.     begin
  192.       write(c);
  193.       s := s+c;
  194.       inc(i);
  195.     end;
  196.  
  197.   until (c = #13) or ((c in [#72, #80]) and ext);
  198.   ReadStr := c;
  199. end;
  200. {-----------------------------------------------------------------------------}
  201. function ReadPart(Y:integer; var P:integer; var Quit:boolean):char;{см. Lab5}
  202. var
  203.     c:char;
  204.     ext: boolean;
  205.     i:integer;
  206. begin
  207.   ClrLine(Y,14);
  208.   if P <> 0 then
  209.   begin
  210.     write(Parts[P]);
  211.     i:=1;
  212.   end;
  213.   Quit:=false;
  214.  
  215.   Message(9,'Выберите часть света, в которой расположена страна');
  216.   GotoXY(1, 10);
  217.   for i:=1 to 6 do
  218.     Writeln(i,' - ', Parts[i]);
  219.   i:= 0;
  220.   GotoXY(14, Y);
  221.   repeat
  222.     c := readkey;
  223.     if c = #27 then
  224.     begin
  225.       Quit := true;
  226.       exit;
  227.     end;
  228.     if c = #0 then ext := true;
  229.     if c in ['1'..'6'] then      
  230.     begin
  231.        ClrLine(Y,14);
  232.         Write(Parts[ord(c)-ord('0')]);
  233.        GotoXY(WhereX-1, WhereY);
  234.        P := ord(c)-ord('0');
  235.     end;
  236.  
  237.   until (c=#13) or ((c in [#72, #80]) and ext);
  238.  
  239.   for i:=0 to 6 do
  240.     Message(9+i, '');
  241.   ReadPart := c;
  242. end;
  243. {-----------------------------------------------------------}
  244. procedure EnterData;
  245. var
  246.  { F: file of Data;}  {файл не используется}
  247.   G: Data;
  248.   c: char;
  249.   f, quit:boolean;
  250.   i, day: word;
  251. begin
  252.   clrscr;
  253.   repeat
  254.     clrscr;
  255.     i := 1;
  256.     G.Country := '';
  257.     G.Part := 0;
  258.     G.Capital := '';
  259.     Writeln('Страна     : ');
  260.     Writeln('Часть света: ');
  261.     Writeln('Столица    : ');
  262.  
  263.     Message(9, 'ESC - возврат в меню');
  264.     repeat
  265.     repeat
  266.       GotoXY(14, i);
  267.       case i of
  268.         1: c := ReadStr(1, G.Country, quit);
  269.         2: c := ReadPart(2, G.Part, quit);
  270.         3: c := ReadStr(3, G.Capital, quit);
  271.       end;
  272.       if quit then
  273.          exit;
  274.  
  275.       if (c in [#72, #80]) then
  276.       begin
  277.         if (c = #72) and (i > 1) then
  278.            dec(i);
  279.         if (c = #80) and (i < 3) then
  280.            inc(i);
  281.        end;
  282.       if (c = #13) and (i < 3) then
  283.       begin
  284.         inc(i);
  285.         c := #0;
  286.       end;
  287.     until (c = #13) and (i = 3);
  288.  
  289.       if G.Country = '' then
  290.       begin
  291.         i := 1;
  292.         f := false;
  293.         end
  294.       else f:= true;
  295.  
  296.       if g.Part = 0 then
  297.         begin
  298.         i:=2;
  299.         f := false;
  300.         end;
  301.       if G.Capital = '' then
  302.         begin
  303.         i:=3;
  304.         f := false;
  305.         end;
  306.        
  307.        if not f then
  308.          Message(9, 'Нужно заполнить все поля');
  309.  
  310.     until f;
  311.  
  312.     PushBack(G); {Сохраняем введенные данные в список}
  313.    until  c = #27;
  314.  
  315. end;
  316.  
  317. Procedure WriteItem(var D:Data); {см. Lab5}
  318. Var
  319.   X,Y, i:integer;
  320.   s:string;
  321. begin
  322.   Y := WhereY;
  323.   GotoXY(2, Y);
  324.   s := D.Country;
  325.   if Length(D.Country)<24 then
  326.      write('│',D.Country)
  327.   else
  328.   begin
  329.     Delete(S, 22 , Length(s) - 21);
  330.     write('│', s+'...');
  331.   end;
  332.  
  333.   GotoXY(27, Y);
  334.   Write('│', Parts[D.Part]);
  335.   GotoXY(52, Y);
  336.   s := D.Capital;
  337.   if Length(D.Capital)<26 then
  338.      write('│',D.Capital)
  339.   else
  340.   begin
  341.     Delete(S, 25 , Length(s) - 25);
  342.     write('│', s+'...');
  343.   end;
  344.  
  345. end;
  346.  
  347. procedure Edit(N:NodePtr); {редактирование элемента, на который указывает указатель N}
  348. var
  349.   t: Data;
  350.   c: char;
  351.   f, quit:boolean;
  352.   i: word;
  353. begin
  354.  
  355.     clrscr;
  356.     t:=N^.D; {Копируем данные из элемента N во временную переменную}
  357.     i := 1;
  358.  
  359.     Writeln('Страна     : ', t.Country);
  360.     Writeln('Часть света: ', Parts[t.Part]);
  361.     Writeln('Столица    : ', t.Capital);
  362.  
  363.     Message(9, 'ESC - возврат в меню');
  364.     repeat
  365.     repeat
  366.       GotoXY(14, i);
  367.       case i of
  368.         1: c := ReadStr(1, t.Country, quit);
  369.         2: c := ReadPart(2, t.Part, quit);
  370.         3: c := ReadStr(3, t.Capital, quit);
  371.       end;
  372.       if quit then
  373.          exit;
  374.  
  375.       if (c in [#72, #80]) then
  376.       begin
  377.         if (c = #72) and (i > 1) then
  378.            dec(i);
  379.         if (c = #80) and (i < 3) then
  380.            inc(i);
  381.        end;
  382.       if (c = #13) and (i < 3) then
  383.       begin
  384.         inc(i);
  385.         c := #0;
  386.       end;
  387.     until (c = #13) and (i = 3);
  388.  
  389.       if t.Country = '' then
  390.       begin
  391.         i := 1;
  392.         f := false;
  393.         end
  394.       else f:= true;
  395.  
  396.       if t.Part = 0 then
  397.         begin
  398.         i:=2;
  399.         f := false;
  400.         end;
  401.       if t.Capital = '' then
  402.         begin
  403.         i:=3;
  404.         f := false;
  405.         end;
  406.  
  407.        if not f then
  408.          Message(9, 'Нужно заполнить все поля');
  409.     until f;
  410.     N^.D := t; {заменяем данные в элементе списка N отредактированными данными}
  411. end;
  412. {---------------------------------------------------------------------------}
  413. Function ShowAll(var I:Data):boolean;far; {см. Lab5}
  414. begin
  415.   ShowAll := True;
  416. end;
  417. {----------------------------------------------------------------------------}
  418. Function Mode1(var I:Data):boolean;far; {см. Lab5}
  419. begin
  420.     if I.Part = Mode1Part then
  421.         Mode1:=true
  422.     else Mode1:=false;
  423. end;
  424. {----------------------------------------------------------------------------}
  425. Function Mode2(var I:Data):boolean;far; {см. Lab5}
  426. begin
  427.     if I.Country = Mode2Country then
  428.         Mode2:=true
  429.     else Mode2:=false;
  430. end;
  431. {----------------------------------------------------------------------------}
  432. Procedure SelectMode(var S:Predicate); {см. Lab5}
  433. var
  434.   c:char;
  435.   i:integer;
  436.   ext, quit:boolean;
  437. begin
  438.   ClrScr;
  439.   writeln('[*] Показывать все записи');
  440.   writeln('[ ] Вывод списка стран, расположенных в заданной части света');
  441.   writeln('[ ] Вывод информации о заданной стране');
  442.   ext := false;
  443.   i := 1;
  444.   repeat
  445.     GotoXY(2, i);
  446.     write('*');
  447.  
  448.     c := readkey;
  449.     if c = #0 then ext := true;
  450.     if (c = #72) and ext and (i > 1) then
  451.     begin
  452.       dec(i);
  453.       GotoXY(2, i+1);
  454.       write(' ');
  455.     end;
  456.     if (c = #80) and ext and (i<3) then
  457.     begin
  458.       inc(i);
  459.       GotoXY(2, i-1);
  460.       write(' ');
  461.     end;
  462.   until c = #13;
  463.   case i of
  464.     1: S := ShowAll;
  465.     2: begin
  466.         S := Mode1;
  467.         ClrScr;
  468.         Write('Часть света:');
  469.         Mode1Part := 0;
  470.         repeat
  471.             c := ReadPart(1, Mode1Part, quit);
  472.         until (c = #13) and (Mode1Part <> 0);
  473.         end;
  474.     3: begin
  475.         S := Mode2;
  476.         ClrScr;
  477.         Write('Страна     : ');
  478.         Mode2Country := '';
  479.         repeat
  480.             c := ReadStr(1, Mode2Country, quit);
  481.         until (c = #13) and (Mode2Country <> '');
  482.         end;
  483.     end;
  484.  
  485. end;
  486. {---------------------------------------------------------------------------}
  487. Procedure Show;
  488. var
  489.   t: Data;
  490.   ip:NodePtr; {указатель на выбранный элемент (на экране) в списке}
  491.   Select:Predicate;
  492.   N, i, j, k, offset, Y:integer;
  493.   c:char;
  494.   ext,scroll, refresh:boolean;
  495. begin
  496.   ClrScr;
  497.   ip := First; {выбран 1-й элемент}
  498.   Current := First; {текущий - 1-й элемент}
  499.   offset := 0;
  500.   if First = nil then {если нет элементов}
  501.   begin
  502.      ClrScr;
  503.      Writeln('Нет записей');
  504.      Writeln('Нажмите любую клавишу чтобы вернуться в меню');
  505.      readkey;
  506.      exit;
  507.   end;
  508.  
  509.   GotoXY(1,2);
  510.   write('*');
  511.   Y := 2;
  512.   j := 1;
  513.   scroll := false;
  514.   refresh := true;
  515.   N := 0;
  516.   offset := 0;
  517.   Select := ShowAll;
  518.   repeat
  519.  
  520.   if (N = 0) or scroll or refresh then
  521.   begin
  522.   if refresh then
  523.   begin
  524.   Message(1,' │        Страна          │       Часть света      │         Столица       ');
  525.   TextBackground(LightGray);
  526.   TextColor(Black);
  527.   Message(25,'Up/Down - навигация  Del - удаление F3 - режим F4 - редактирование  ESC - выход');
  528.  
  529.   TextColor(LightGray);
  530.   TextBackground(Black);
  531.   end;
  532.   for i:=2 to 24 do ClrLine(i,1);
  533.   i := offset*22 + 1;
  534.   ip := First;
  535.   for i:=1 to Offset*22 do {переместимся в списке к блоку из 22 элементов}
  536.       if ip^.Next <> Nil then {если следующий элемент существует, то}
  537.       ip := ip^.Next; {перейти к нему}
  538.   if Offset > 0 then ip := ip^.Next;
  539.   k:=1;
  540.   GotoXY(3, 2);
  541.  
  542.   while (ip<>nil) and (k<=23) do
  543.   begin
  544.     if Select(ip^.D) then
  545.        begin
  546.        WriteItem(ip^.D);
  547.        inc(k);
  548.        GotoXY(3, 1+k);
  549.        end;
  550.        ip := ip^.next;
  551.   end;
  552.     N := k - 1;
  553.   if N = 0 then
  554.   begin
  555.      ClrScr;
  556.      Writeln('Нет записей');
  557.      Writeln('ESC - вернуться в меню');
  558.      Writeln('F3  - выбрать режим');
  559.      c := readkey;
  560.      if c = #0 then c:=readkey;
  561.      if c = #61 then
  562.      begin
  563.        SelectMode(Select);
  564.        Refresh := true;
  565.        offset := 0;
  566.        Y:=2;
  567.        Close(F);
  568.        Continue;
  569.      end;
  570.      if c = #27 then
  571.         exit;
  572.   end;
  573.   GotoXY(1,Y);
  574.   write('*');
  575.   Scroll := false;
  576.   refresh := false;
  577.   end;
  578.  
  579.   repeat
  580.     c := readkey;
  581.     if c = #0 then ext := true;
  582.     if (c = #83) and ext then
  583.     begin
  584.        clrscr;
  585.        writeln('Удалить? y/n');
  586.        repeat
  587.          c := readkey;
  588.          if UpCase(c) = 'Y' then
  589.          begin
  590.             if not Select(Current^.D) then
  591.             begin
  592.             Current := ip;
  593.             repeat
  594.             Current := Current^.Next;
  595.             until (Current = Nil) or Select(Current^.D);
  596.             end;
  597.            
  598.             ListDelete(Current);
  599.  
  600.             if N = 1 then
  601.             begin
  602.                 Y := 25;
  603.                 j := 23;
  604.                 dec(Offset);
  605.             end;
  606.             break;
  607.          end;
  608.        until UpCase(c) = 'N';
  609.  
  610.        if j > 1 then dec(j);
  611.        if Y > 2 then dec(Y);
  612.        refresh := true;
  613.        break;
  614.     end;
  615.     if (c = #61) and ext then
  616.     begin
  617.       SelectMode(Select);
  618.       j := 1;
  619.       Y := 2;
  620.       offset := 0;
  621.       Current := First;
  622.       Refresh := true;
  623.       break;
  624.     end;
  625.     if (c = #62) and ext then
  626.     begin
  627.       Edit(Current);
  628.       refresh := true;
  629.       break;
  630.     end;
  631.     if (c = #72) and ext and (Y >= 2) then
  632.     begin
  633.        if (Y = 2) and (j >= 1) then
  634.        begin
  635.          if offset > 0 then
  636.          begin
  637.               dec(offset);
  638.               if Current^.Prev <> Nil then
  639.                 repeat
  640.                     Current := Current^.Prev;
  641.                 until (Select(Current^.D) or (Current^.Prev = Nil));
  642.               Scroll := true;
  643.               Y:=24;
  644.               j:=23;
  645.               break;
  646.          end
  647.        end;
  648.  
  649.        if j > 1 then dec(j);
  650.        if Y > 2 then dec(Y);
  651.        if Current <> First then
  652.        repeat
  653.              Current := Current^.prev;
  654.        until Select(Current^.D) or (Current^.Prev = Nil);
  655.        GotoXY(1, Y+1);
  656.        write(' ');
  657.        GotoXY(1, Y);
  658.        write('*');
  659.     end;
  660.  
  661.     if (c = #80) and ext and (Y <= N+1) then
  662.     begin
  663.       if (Y = 24) and (Current^.Next <> Nil) then
  664.       begin
  665.         inc(offset);
  666.         repeat
  667.               Current := Current^.Next;
  668.         until Select(Current^.D) or (Current^.Next = Nil);
  669.         scroll := true;
  670.         Y := 2;
  671.         j := 1;
  672.         break;
  673.       end;
  674.  
  675.       If (Y <= N) and (Current^.Next <> Nil) then
  676.       begin
  677.         inc(j);
  678.         inc(Y);
  679.         repeat
  680.               Current:=Current^.next;
  681.         until Select(Current^.D) or (Current^.Next = Nil);
  682.         GotoXY(1, Y-1);
  683.         write(' ');
  684.         GotoXY(1, Y);
  685.         write('*');
  686.       end;
  687.     end;
  688.   until (c in [#72, #80]) and ext or (c = #27);
  689.   until c = #27;
  690. end;
  691.  
  692.  
  693. begin
  694.   clrscr;
  695.   assign(F, 'base.dat');
  696.   {$I-}
  697.   reset(F);
  698.   {$I+}
  699.   if IOResult <> 0 then
  700.     rewrite(F);
  701.   while not EOF(F) do {Считывание данных из файла}
  702.   begin
  703.     read(F, i);
  704.     PushBack(i); {Занесем данные в список}
  705.   end;
  706.   close(F);
  707.  { Current := First;
  708.   while Current <> nil do
  709.     Current := Current^.Next;
  710.   }
  711.   repeat
  712.     Mode := Menu;
  713.     case Mode of
  714.       1: EnterData;
  715.       2: Show;
  716.       end;
  717.   until mode = 3;
  718.   Current := First;
  719.   Rewrite(F); {Сотрем файл и запишем в него данные}
  720.   while Current <> Nil do
  721.   begin
  722.     Write(F, Current^.D); {Запись данных }
  723.     Current := Current^.Next; {переход к следующему элементу}
  724.   end;
  725.   close(F);
  726. end.
Add Comment
Please, Sign In to add comment