Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.03.25;
Скачать: [xml.tar.bz2];

Вниз

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

 
Василиус ©   (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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.04 c
15-1172731482
Cyrax
2007-03-01 09:44
2007.03.25
AllFusion ERwin Data Modeler: проблема имён


2-1172740254
Riply
2007-03-01 12:10
2007.03.25
Утечка памяти при передаче нити дин. массива как параметра.


3-1165578287
valwin
2006-12-08 14:44
2007.03.25
Доступ из Delphi к БД *.fdb т.е. FireBird через комп-ты Interbase


11-1151524737
Flea
2006-06-28 23:58
2007.03.25
ItemAtPos


4-1162362348
romick
2006-11-01 09:25
2007.03.25
Как проверить наличие бумаги в USB-принтере?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский