Ron_de_Weijze
asked on
'ReadLn across lines'
Hi,
My problem seems to be with ReadLn. The following is code I have not written (but did pay for). I cannot get it to work. It does work in a compiled version from many years ago.
A line (0ÿNew Noteÿÿÿ-1ÿ80ÿ50ÿ65535ÿ16ÿ0 ÿ1ÿ10ÿaþ
bÿ-1) in a datafile is read using
procedure TNotePool.Load(FileName : string);
var
DataFile : TextFile;
Line : string;
Note : TNote;
begin
AssignFile(DataFile, FileName);
Reset(DataFile);
while not EOF(DataFile) do
begin
Readln(DataFile, Line);
Note.ID := StrToInt(GetFieldFromLine( Line));
Note.Caption := GetFieldFromLine(Line);
Note.ImageFile := GetFieldFromLine(Line);
Note.IconFile := GetFieldFromLine(Line);
Note.NoteType := StrToInt(GetFieldFromLine( Line));
Note.Width := StrToInt(GetFieldFromLine( Line));
Note.Height := StrToInt(GetFieldFromLine( Line));
Note.Color := StrToInt(GetFieldFromLine( Line));
Note.IconSize := StrToInt(GetFieldFromLine( Line));
Note.IconLocation := StrToInt(GetFieldFromLine( Line));
Note.Transparent := Boolean(StrToInt(GetFieldF romLine(Li ne)));
Note.TextSize := StrToInt(GetFieldFromLine( Line));
Note.Memo := SetCRs(GetFieldFromLine(Li ne));
{ ATTENTION : TEMPORARILY }
Note.AggID := StrToInt(Line);
if OldLoad then
AddItem(Note)
else
AddItemRaw(Note);
end;
CloseFile(DataFile);
end;
The line that is read is cut into a first part on line 1 of the datafile and a second part on line 2 of the datafile. The line that is read must be put into the note (Memo field) and it must be cut in half (continuing after the carriage return) on the memo. Now, the line-separator þ (#254) that is used is not recognized by the
function TPool.GetFieldFromLine(var Str : string) : string;
var
Temp : string;
begin
Temp := Copy(Str, 1, Pos(#255, Str) - 1);
System.Delete(Str, 1, Pos(#255, Str));
Result := Temp;
end;
Therefore, the memo field remains empty and an exception is raised.
Strangely,
function TPool.SetCRs(Text : ansistring) : ansistring;
var
i : longint;
TempText : ansistring;
begin
for i := 1 to Length(Text) do
begin
if Text[i] = #254 then
TempText := TempText + #13
else
TempText := TempText + Text[i];
end;
Result := TempText;
end;
is supposed to work with the extracted memo-field, but, of course, if empty, it cannot.
Do you see how this is supposed to work? I will say this question is difficult, but I am clearly a beginner..
Thanks,
Ron dW
My problem seems to be with ReadLn. The following is code I have not written (but did pay for). I cannot get it to work. It does work in a compiled version from many years ago.
A line (0ÿNew Noteÿÿÿ-1ÿ80ÿ50ÿ65535ÿ16ÿ0
bÿ-1) in a datafile is read using
procedure TNotePool.Load(FileName : string);
var
DataFile : TextFile;
Line : string;
Note : TNote;
begin
AssignFile(DataFile, FileName);
Reset(DataFile);
while not EOF(DataFile) do
begin
Readln(DataFile, Line);
Note.ID := StrToInt(GetFieldFromLine(
Note.Caption := GetFieldFromLine(Line);
Note.ImageFile := GetFieldFromLine(Line);
Note.IconFile := GetFieldFromLine(Line);
Note.NoteType := StrToInt(GetFieldFromLine(
Note.Width := StrToInt(GetFieldFromLine(
Note.Height := StrToInt(GetFieldFromLine(
Note.Color := StrToInt(GetFieldFromLine(
Note.IconSize := StrToInt(GetFieldFromLine(
Note.IconLocation := StrToInt(GetFieldFromLine(
Note.Transparent := Boolean(StrToInt(GetFieldF
Note.TextSize := StrToInt(GetFieldFromLine(
Note.Memo := SetCRs(GetFieldFromLine(Li
{ ATTENTION : TEMPORARILY }
Note.AggID := StrToInt(Line);
if OldLoad then
AddItem(Note)
else
AddItemRaw(Note);
end;
CloseFile(DataFile);
end;
The line that is read is cut into a first part on line 1 of the datafile and a second part on line 2 of the datafile. The line that is read must be put into the note (Memo field) and it must be cut in half (continuing after the carriage return) on the memo. Now, the line-separator þ (#254) that is used is not recognized by the
function TPool.GetFieldFromLine(var
var
Temp : string;
begin
Temp := Copy(Str, 1, Pos(#255, Str) - 1);
System.Delete(Str, 1, Pos(#255, Str));
Result := Temp;
end;
Therefore, the memo field remains empty and an exception is raised.
Strangely,
function TPool.SetCRs(Text : ansistring) : ansistring;
var
i : longint;
TempText : ansistring;
begin
for i := 1 to Length(Text) do
begin
if Text[i] = #254 then
TempText := TempText + #13
else
TempText := TempText + Text[i];
end;
Result := TempText;
end;
is supposed to work with the extracted memo-field, but, of course, if empty, it cannot.
Do you see how this is supposed to work? I will say this question is difficult, but I am clearly a beginner..
Thanks,
Ron dW
ASKER
Thanks for your comment, Andrew.
I agree that the line shouldn't be cut in the datafile.
However, this seems to be the way that the datafile is written in..
procedure TNotePool.Save(FileName : string);
var
DataFile : TextFile;
i : integer;
begin
AssignFile(DataFile, FileName);
Rewrite(DataFile);
for i := 0 to Count - 1 do
begin
WriteLn(DataFile,
i, #255,
TNoteItem(Item[i]).Caption , #255,
TNoteItem(Item[i]).ImageFi le, #255,
TNoteItem(Item[i]).IconFil e, #255,
TNoteItem(Item[i]).NoteTyp e, #255,
TNoteItem(Item[i]).Width, #255,
TNoteItem(Item[i]).Height, #255,
TNoteItem(Item[i]).Color, #255,
TNoteItem(Item[i]).IconSiz e, #255,
TNoteItem(Item[i]).IconLoc ation, #255,
integer(TNoteItem(Item[i]) .Transpare nt), #255,
TNoteItem(Item[i]).TextSiz e, #255,
KillCRs(TNoteItem(Item[i]) .Memo), #255,
{ ATTENTION : TEMPORARILY }
m_SheetPool.m_ItemList.Ind exOf(TNote Item(Item[ i]).
AggItem)
);
end;
CloseFile(DataFile);
end;
using..
function TPool.KillCRs(Text : ansistring) : ansistring;
var
i : longint;
TempText : ansistring;
begin
for i := 1 to Length(Text) do
begin
if Text[i] = #13 then
TempText := TempText + #254
else
TempText := TempText + Text[i];
end;
Result := TempText;
end;
Or would you say this code is nòt supposed to cut the line to be written in half after the þ line separator onto the datafile?
Thanks
I agree that the line shouldn't be cut in the datafile.
However, this seems to be the way that the datafile is written in..
procedure TNotePool.Save(FileName : string);
var
DataFile : TextFile;
i : integer;
begin
AssignFile(DataFile, FileName);
Rewrite(DataFile);
for i := 0 to Count - 1 do
begin
WriteLn(DataFile,
i, #255,
TNoteItem(Item[i]).Caption
TNoteItem(Item[i]).ImageFi
TNoteItem(Item[i]).IconFil
TNoteItem(Item[i]).NoteTyp
TNoteItem(Item[i]).Width, #255,
TNoteItem(Item[i]).Height,
TNoteItem(Item[i]).Color, #255,
TNoteItem(Item[i]).IconSiz
TNoteItem(Item[i]).IconLoc
integer(TNoteItem(Item[i])
TNoteItem(Item[i]).TextSiz
KillCRs(TNoteItem(Item[i])
{ ATTENTION : TEMPORARILY }
m_SheetPool.m_ItemList.Ind
AggItem)
);
end;
CloseFile(DataFile);
end;
using..
function TPool.KillCRs(Text : ansistring) : ansistring;
var
i : longint;
TempText : ansistring;
begin
for i := 1 to Length(Text) do
begin
if Text[i] = #13 then
TempText := TempText + #254
else
TempText := TempText + Text[i];
end;
Result := TempText;
end;
Or would you say this code is nòt supposed to cut the line to be written in half after the þ line separator onto the datafile?
Thanks
ASKER
BTW I wìll look into Line.Length() and let you know.
Indeed - it should remove the CRs so the line isn't cut.
Perhaps there's a LF got into there somehow.
Perhaps it's not really cut and it's just how your viewing it..
Perhaps there's a LF got into there somehow.
Perhaps it's not really cut and it's just how your viewing it..
ASKER
Thanks, I'll investigate and let you know ASAP!
getting this result
0
New Note
-1
80
50
65535
16
0
1
10
aþb
-1
using this sample
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function SplitStr(Var AString : String; ADelim : String) : String;
var APos : Integer;
begin
Result := '';
APos := Pos(ADelim,AString);
if APos > 0 then
begin
Result := Copy(AString,1,APos-1);
AString := copy(Astring,APos+length(A delim),Max LongInt);
end
else
begin
Result := AString;
AString := '';
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
var s : string;
begin
s := edit1.text;
memo1.lines.clear;
while s <> '' do
memo1.lines.add(splitstr(s ,#255));
end;
end.
meikl ;-)
0
New Note
-1
80
50
65535
16
0
1
10
aþb
-1
using this sample
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function SplitStr(Var AString : String; ADelim : String) : String;
var APos : Integer;
begin
Result := '';
APos := Pos(ADelim,AString);
if APos > 0 then
begin
Result := Copy(AString,1,APos-1);
AString := copy(Astring,APos+length(A
end
else
begin
Result := AString;
AString := '';
end;
end;
procedure TForm1.Button1Click(Sender
var s : string;
begin
s := edit1.text;
memo1.lines.clear;
while s <> '' do
memo1.lines.add(splitstr(s
end;
end.
meikl ;-)
ASKER
Thanks Andrew and Meikl,
The line is *really* cut in the datafile, for this is true after looking at the line ("a" over "b" in a note) written by the compiled code and the current code using EditPad. The line produced by the current code can be read by the compiled code but it cannot be read by the current code.
Text and Length(Text) in TPool.KillCRs are:
Text: 'a'#$D#$A'b'
Length(Text): Inaccessible value
I do not see LF #10.
I wished I'd understand this, otherwise I might resort to code like Meikl's.
Thanks again.
The line is *really* cut in the datafile, for this is true after looking at the line ("a" over "b" in a note) written by the compiled code and the current code using EditPad. The line produced by the current code can be read by the compiled code but it cannot be read by the current code.
Text and Length(Text) in TPool.KillCRs are:
Text: 'a'#$D#$A'b'
Length(Text): Inaccessible value
I do not see LF #10.
I wished I'd understand this, otherwise I might resort to code like Meikl's.
Thanks again.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you both!
I changed the
if Text[i] = #13
in KillCRs into
if Text[i] = #$A then
TempText := TempText + #254
else if Text[i] = #$D then
TempText := TempText
Looks like a change in Delphi itself (I use version 7.0)?
Case closed (for now).
Hope you don't mind sharing the points! :)
I changed the
if Text[i] = #13
in KillCRs into
if Text[i] = #$A then
TempText := TempText + #254
else if Text[i] = #$D then
TempText := TempText
Looks like a change in Delphi itself (I use version 7.0)?
Case closed (for now).
Hope you don't mind sharing the points! :)
The code looks OK (though there's no error handling at all).
After the ReadLn( DataFile , Line)
see how long 'Line' is
i.e. Line.Length()