Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.03.25;
Скачать: CL | DM;

Вниз

помогите позжалста...   Найти похожие ветки 

 
Василиус ©   (2007-02-27 21:12) [0]

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

вот листинг

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TPcar=^Tcar; //указатель на тип TStudent

 Tcar = record
   vlad:string[30];  // фамилия
  mark,nom,tm: string[30]; // имя
   dat:string[30];
   prob:string[30];
next: TPcar;    // следующий элемент списка
 end;

 fcar=file of TPcar;
 TForm2 = class(TForm)
   GroupBox1: TGroupBox;
   Edit1: TEdit;
   Edit2: TEdit;
   Edit3: TEdit;
   Edit4: TEdit;
   Edit5: TEdit;
   Label1: TLabel;
   Label2: TLabel;
   Label3: TLabel;
   Label4: TLabel;
   Label5: TLabel;
   Label6: TLabel;
   ComboBox1: TComboBox;
   Label7: TLabel;
   Label8: TLabel;
   Label9: TLabel;
   Button1: TButton;
   Button2: TButton;
   procedure cls(Sender: TObject; var Action: TCloseAction);
   procedure Button1Click(Sender: TObject);
   procedure pr(Sender: TObject; var Key: Char);
   procedure pre(Sender: TObject; var Key: Char);
   procedure act(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

var
head,curr: TPcar;
f: fcar;
procedure TForm2.cls(Sender: TObject; var Action: TCloseAction);

begin
form1.show;
form2.hide;
closefile(f);
end;

procedure TForm2.Button1Click(Sender: TObject);

{curr: TPcar; }

begin

new(curr);

curr^.vlad := Edit1.Text;

curr^.mark := Edit2.Text;

curr^.nom := Edit3.Text;

curr^.dat := Edit4.Text;

curr^.prob := Edit5.Text;

curr^.tm := combobox1.Text;

curr^.next := head;
head := curr;

write(f,curr);\\вот тут то и возникаю т проблемы...в приложении для считывания(далее) есть анологичный алгоритм считывания...
нипашет.

edit1.Text:="";
edit2.Text:="";
edit3.Text:="";
edit4.Text:="";
edit5.Text:="";
combobox1.Text:="";

end;

procedure TForm2.pr(Sender: TObject; var Key: Char);
begin
case key of
#44:;
#48..#58:;
#8:;
else
key:=char(0);
end;
end;

procedure TForm2.pre(Sender: TObject; var Key: Char);
begin
case key of
#44:;
#48..#58:;
#8:;
else
key:=char(0);
end;
end;

procedure TForm2.act(Sender: TObject);
var
 resp : word;

begin
 AssignFile(f, "C:\c.dat");
 {$I-}
 Reset(f);
 Seek( f,  FileSize(f) );
 {$I+}
 if IOResult = 0
    then button1.enabled:=TRUE
    else
      begin
        resp:=MessageDlg("Файл базы данных не найден."+
                          "Создать новую БД?",mtInformation,[mbYes,mbNo],0);
        if resp = mrYes then
             begin
               {$I-}
               rewrite(f);
               {$I+}
               if IOResult = 0
                  then button1.enabled:=TRUE
                  else ShowMessage("Ошибка создания файла.");
             end;
      end;
end;

procedure TForm2.Button2Click(Sender: TObject);
var
{ curr: TPcar;}  // текущий элемент списка
n:integer;        // длина (кол-во элементов) списка
st:string;        // строковое представление списка
begin
n := 0;
st := "";
curr := head;  // указатель на первый элемент списка
while curr <> NIL do
   begin
     n := n + 1;
     st := st + curr^.vlad + " " + curr^.mark +#13;
     curr := curr^.next;  // указатель на следующий элемент
   end;

if n <> 0
   then ShowMessage("Список:" + #13 + st)
   else ShowMessage("В списке нет элементов.");

end;

end.

вот листинг второго приложения

unit Unit3;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Grids, StdCtrls;

type
TPcar=^Tcar; //указатель на тип TStudent

 Tcar = record
   vlad:string[30];  // фамилия
  mark,nom,tm: string[30]; // имя
   dat:string[30];
   prob:string[30];
next: TPcar;    // следующий элемент списка
 end;
 fcar=file of TPcar;

 TForm3 = class(TForm)
   StringGrid1: TStringGrid;
   Button1: TButton;
   Label1: TLabel;
   procedure close(Sender: TObject; var Action: TCloseAction);
   procedure activ(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form3: TForm3;

implementation

uses Unit1;

{$R *.dfm}


var
hed,cur: TPcar;
ff: fcar;

procedure TForm3.close(Sender: TObject; var Action: TCloseAction);
begin
form3.Hide;
form1.show;
closefile(ff);
end;

procedure TForm3.activ(Sender: TObject);

begin
assignfile(ff,"c:\c.dat");
reset(ff);
while not eof(ff) do begin
new(cur);

read(ff,cur);

cur^.next := hed;
hed := cur;

end;
end;

procedure TForm3.Button1Click(Sender: TObject);
var
n:integer;        // длина (кол-во элементов) списка
st:string;        // строковое представление списка
begin
n := 0;
st := "";
cur := hed;  // указатель на первый элемент списка
while cur <> NIL do
   begin
     n := n + 1;
     st := st + cur^.vlad + " " + cur^.mark +#13;
     cur := cur^.next;  // указатель на следующий элемент
   end;
label1.Caption:=inttostr(n);
if n <> 0
   then ShowMessage("Список:" + #13 + st)
   else ShowMessage("В списке нет элементов.");

end;

end.


 
Аноним   (2007-02-27 22:17) [1]

type
PCar=^TCar;
TCar= packed record
  vlad:string[30];  // фамилия
  mark,nom,tm: string[30]; // имя
  dat:string[30];
  prob:string[30];
end;

var
 CarList: Tlist;//Список указателей PCar

procedure SaveListToFile(FileName: string);
var
 N, I: Integer;
 Item: PCar;
 FS: TFileStream;
begin
 N:=CarList.Count;
 FS:=TFileStream.Create(FileName, fmCreate);
 try
   FS.WriteBuffer(N, SizeOf(N));
   for I:=0 to CarList.Count - 1 do
     begin
       Item:=CarList[I];
       FS.WriteBuffer(Item^, SizeOf(Item^));
     end;
 finallly
   FS.Free;
 end;
end;

procedure LoadListFromFile(FileName: string);
var
 N, I: Integer;
 Item: PCar;
 FS: TFileStream;
begin
 N:=CarList.Count;
 FS:=TFileStream.Create(FileName, fmOpenRead);
 try
   FS.ReadBuffer(N, SizeOf(N));
   for I:=0 to N - 1 do
     begin
       New(Item);
       FS.ReadBuffer(Item^, SizeOf(Item^));
       CarList.Add(Item);
     end;
 finallly
   FS.Free;
 end;
end;


 
Чайник глазами самовара   (2007-02-27 23:38) [2]


> Аноним   (27.02.07 22:17) [1]
</I
>   FS.ReadBuffer(N, SizeOf(N));

>

- здесь что то непонятно...


 
Аноним   (2007-02-27 23:59) [3]


> - здесь что то непонятно...


А чего тут непонятно
считываем сначала из потока ранее записаное количество элементов в спискев переменную N, потом огранизуем цикл по количеству элементов и считываем их из потока, добавляем в список.

Надо еще не забыть при очищении списка освобождать память, занимаемую записями


 
koha ©   (2007-02-28 04:18) [4]

Var N, I: Integer;

FS.ReadBuffer(N, SizeOf(N));

ReadBuffer - Предположительно должно в буфер считывать. N- вуфер?


 
Elen ©   (2007-02-28 08:02) [5]

А мне кажется что собака порылась вот тут :
type
TPcar=^Tcar; //указатель на тип TStudent

Tcar = record
  vlad:string[30];  // фамилия
 mark,nom,tm: string[30]; // имя
  dat:string[30];
  prob:string[30];
next: TPcar;    // следующий элемент списка
end;

fcar=file of TPcar;


Вот оно и организовывает файл указателей. Попробуй fcar=file of Tcar;


 
Аноним   (2007-02-28 09:48) [6]


> koha ©


> N- вуфер?


Разумееся. Память под него (все 4 байта) выделена компилером автоматически


 
koha ©   (2007-02-28 19:06) [7]


> Аноним   (28.02.07 09:48) [6]
> > koha © > N- вуфер?Разумееся. Память под него (все 4 байта)
> выделена компилером автоматически


я может что не допонимаю, но зачем такие сложности придумывать вот предлагаю свое решение проблемы.
Причем испытывал  все прекрасно работает.

type
 Tcar = record
 vlad:string[30];  // фамилия
 mark,nom,tm: string[30]; // имя
 dat:string[30];
 prob:string[30];
 end;

//..............................

procedure CardRead;
procedure CardWrite;

//..............................

Var  
 FStrm : TFileStream;
 Card  : Tcar;

//..............................

Begin
procedure CardWrite;
begin
 try
   try
     FStrm:=TFileStream.Create("c:\Newfile.dat",fmCreate);
     FStrm.Write(Card,SizeOf(Card));
   finally
     Fstrm.Free;
   end;
 except
   MessageBox(Handle,PChar("Ошибка"),
     PChar("Произошла ошибка при записи данных.",MB_ICONERROR));
 end;
end;

procedure CardRead;
begin
 try
   try
     FStrm:=TFileStream.Create("c:\Newfile.dat",fmOpenRead);
     FStrm.Read(Card,SizeOf(Card));
   finally
     FStrm.Free;
   end;
   WriteMemo;
 except
   MessageBox(Handle,PChar("Ошибка"),
     PChar("Произошла ошибка при чтении данных.",MB_ICONERROR));
 end;
end;

end.


 
Аноним   (2007-02-28 22:38) [8]


> koha ©  


Ну и что?

Ты тут во первых, предлагаешь код записи одного элемента в файл ,а не списка
во вторых, этот код весь глючный.
Вот, например:

  try
    FStrm:=TFileStream.Create("c:\Newfile.dat",fmOpenRead);
    FStrm.Read(Card,SizeOf(Card));
  finally
    FStrm.Free;
  end;


И что будет, если файл "c:\Newfile.dat" не существует?
Я вот полагаю, что будет "инвалид поинтер оперейшн"
потому что начнем разрушать неинициализированный объект файлстрим
далее

это еще и сокрытие возможной ошибки.
Смотрим.

FStrm.Read(Card,SizeOf(Card));

что будет в случае, если файл существет, но там записано что-то не то? например один нулевой байт?
Будет то, что мы считаем фигню, и не узнаем об этом в момент чтения. Потому что нет исключения

далее:

except
  MessageBox(Handle,PChar("Ошибка"),
    PChar("Произошла ошибка при чтении данных.",MB_ICONERROR));
end;


Ну и что? Какую информацию пытаетсся донести до пользователя автор?
Какая именно ошибка? нет такого файла? или он есть но битый? или может память закончилась в программе?
Не узнаем.
Если ни дай бог, процедура  CardRead не последняя в стеке адресов возврата, то как вызывающий узнает об ошибке?
А если вызывающий - сервис, который крутитя на сервере и где адмиа неделями не бывает?

Спрашвается: нафига тут вообще except

Вот такая критика.


 
koha ©   (2007-03-01 01:22) [9]

На счет except согласен - нахрен ненужен это сокрытие ошибки.

> И что будет, если файл "c:\Newfile.dat" не существует?

- будет тоже, что и в твоем коде, ведь у тебя тоже нет ни какой проверки наличия файла, а в моем по крайней мере except хотя бы но одну ошибку да перехватил бы.

- поэтому можно всегда вставить конструкцию:

if Not FileExists(FileName) then begin
  ShowMessage("file not find");
  Exit;
end;


> что будет в случае, если файл существет, но там записано что-то не то? например один нулевой байт?
- такое же ждал и твой код. Да и как заранее можешь знать какое количество элементов списка было записано в фай? Ведь читается у тебя без проверки количества: ты думаешь что там 6 а вдруг окажется 5.

- с остальным согласен.


 
Аноним   (2007-03-01 10:17) [10]


> koha ©


> > И что будет, если файл "c:\Newfile.dat" не существует?
>
>
> - будет тоже, что и в твоем коде


А вот и нет.
У меня в конструкторе Файл-стрима поднимется осмысленное исключение, дескать "файла нету".
И мы вылетим из процедцуры
А У тебя тоже самое произойдет, но внутри секции try
Соответственно при получении исключения мы попадем в finally, где идет разрушение файл стрима, который не создан (точнее он создан и автоматически разрушен, так как произошло исключение в конструкторе, ну а переменная FStrm осталась не инициализирована).
И Результирующее исключение будет не "файла нету", а "вы мне тут нафиг всю память испортили".


> - поэтому можно всегда вставить конструкцию:
>
> if Not FileExists(FileName) then begin
>   ShowMessage("file not find");
>   Exit;
> end;


не надо вставлять такую конструкцию. Почему - по двум причинам.
1. Если код используется на сервере, и работает в автоматическом режиме, кто придет и нажмет кнопку? так и будет висеть этот мессадж пока админу пистон не вставят, что у него сервис не работает.
2. Если эту функцию вызывает другая функция, она не узнает о проблеме


> > что будет в случае, если файл существет, но там записано
> что-то не то? например один нулевой байт?
> - такое же ждал и твой код. Да и как заранее можешь знать
> какое количество элементов списка было записано в фай? Ведь
> читается у тебя без проверки количества: ты думаешь что
> там 6 а вдруг окажется 5.


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

Короче, мораль такая
1. Создание \ разрушение объекта с использованием секций try finally всегда делается в виде
Создание
try
finally
разрушение
end;
То есть создание перед try а не после

2. Не надо бояться исключений и давить их. Вообще в 90 процентах случаев если в секции except  нет raise, то это ошибка проектирования



Страницы: 1 вся ветка

Текущий архив: 2007.03.25;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.049 c
15-1172479522
xayam
2007-02-26 11:45
2007.03.25
Музыка из фильма Призрачный гонщик


15-1172751648
Prohodil Mimo
2007-03-01 15:20
2007.03.25
Есть ли компонент типа TMenu, позволяющий менять фонт?


1-1170357188
IMHO
2007-02-01 22:13
2007.03.25
Определить кодировку и раскодировать


2-1172740953
tia
2007-03-01 12:22
2007.03.25
DLL


15-1172752338
@!!ex
2007-03-01 15:32
2007.03.25
Просьба сделать в поиске настраиваемый фильтр.