Форум: "Начинающим";
Текущий архив: 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