Avatar billede monie Nybegynder
02. april 2004 - 12:54 Der er 12 kommentarer og
1 løsning

Teksten udskrives ikke Korrekt efter brug af StringReplace

Hvad går der er galt her?

Jeg skal kører proceduren Replay 2 gange for, at få Nick Name ændret,
de andre ændre sig ved første gennemkørsel.

procedure TForm1.replayClick(Sender: TObject);
Var
i: Integer;
begin
For i := 0 to Memo1.lines.count -1 do begin
Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<First Name>',FirstName, [rfReplaceAll, rfIgnoreCase]);
Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<Last Name>',LastName, [rfReplaceAll, rfIgnoreCase]);
Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<Nick Name>',NickName, [rfReplaceAll, rfIgnoreCase]);
Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<Mother Name>',MotherName, [rfReplaceAll, rfIgnoreCase]);
RichEdit1.Lines.Add(Memo1.lines[i]);
end;
end;


Historiebogien her som er skrevet som "bog.txt" som indlæses

if OpenDialog1.Execute then

  Memo1.Lines.LoadFromFile(OpenDialog1.FileName)


Her er "bog.txt" (Test)

<Father Name> ønskede <Mother Name> tilykke med fødselsdagsbogen i dag.
<Mother Name> var glad og <Nick Name>, som var hans kællenavn.

Med venlig hilsen

<First Name> <Last Name>
***End

Håber meget du vil hjælpe, tros, jeg ikke har så mange point!

Med venlig hilsen
Monie Jacobsen
Avatar billede hrc Mester
02. april 2004 - 13:48 #1
Hej Monie. Jeg prøvede din løsning og min nedenfor. Begge løsninger fandt de søgte ord og alt blev erstattet som det skulle. Eneste ting jeg måske kan påpege er, at du søger efter <First Name> mens din tekstfil indeholder <Father Name>.

procedure TForm1.Button1Click(Sender: TObject);
var
  st : string;
  FirstName, LastName, NickName, MotherName : string;
begin
  FirstName  := 'Pelle';
  LastName  := 'Voigt';
  NickName  := 'Pjevs';
  MotherName := 'Christensen';

  Memo1.Lines.Clear;
  Memo1.Lines.LoadFromFile('c:\test.txt');

  RichEdit1.Lines.Clear;

  st := Memo1.Lines.Text;

  st := StringReplace(st,'<First Name>', FirstName,  [rfReplaceAll, rfIgnoreCase]);
  st := StringReplace(st,'<Last Name>',  LastName,  [rfReplaceAll, rfIgnoreCase]);
  st := StringReplace(st,'<Nick Name>',  NickName,  [rfReplaceAll, rfIgnoreCase]);
  st := StringReplace(st,'<Mother Name>',MotherName, [rfReplaceAll, rfIgnoreCase]);

  Memo1.Lines.Text := st;
  RichEdit1.Lines.Assign(Memo1.Lines);
end;
Avatar billede monie Nybegynder
02. april 2004 - 14:14 #2
Den erstatter stadig ikke alle ord!

Her er hele min Unit.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, LMDCustomButton, LMDButton, LMDCustomControl,
  LMDCustomPanel, LMDCustomBevelPanel, LMDBaseEdit, LMDCustomEdit,
  LMDCustomBrowseEdit, LMDBrowseEdit, LMDCustomFileEdit, LMDFileOpenEdit,
  ComCtrls, MinUnits;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    LMDButton1: TLMDButton;
    LMDFileOpenEdit1: TLMDFileOpenEdit;
    RichEdit1: TRichEdit;
    replay: TLMDButton;
    LMDButton3: TLMDButton;
    Edit1: TEdit;
    LMDButton2: TLMDButton;
    Edit2: TEdit;
    LMDButton4: TLMDButton;
    LMDButton5: TLMDButton;
    Edit3: TEdit;
    Edit4: TEdit;
    Button1: TButton;
    procedure LMDButton1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure LMDFileOpenEdit1Click(Sender: TObject);
    procedure replayClick(Sender: TObject);
    procedure LMDButton3Click(Sender: TObject);
    procedure LMDButton2Click(Sender: TObject);
    procedure LMDButton4Click(Sender: TObject);
    procedure LMDButton5Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }

  end;

var
  Form1: TForm1;
  FirstName, LastName, NickName,MotherName, Default : string;
 
implementation

{$R *.dfm}

function ArrangeText(Text : string) : string;
var
I : Integer;
B : Boolean;
begin
Result := Text;
B := True;
for I := 1 to Length(Result) do
begin
if B then
begin
Result[I] := AnsiUpperCase(Result[I])[1];
B := False;
end
else
Result[I] := AnsiLowerCase(Result[I])[1];
if Result[I] = ' ' then
B := True;
end;
end;


procedure TForm1.LMDButton1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
Edit4.Clear;
Memo1.Clear;
RichEdit1.Clear;
end;

procedure TForm1.LMDFileOpenEdit1Click(Sender: TObject);
Var
  filnavn : STRING;
begin
    begin
          Memo1.Clear;
          Memo1.Lines.LoadFromFile(LMDFileOpenEdit1.Filename);
          filnavn := LMDFileOpenEdit1.Filename;
    end;
end;

procedure TForm1.LMDButton3Click(Sender: TObject);
begin
FirstName := ArrangeText(IndskrivSaetning('Indskriv First Name:',Default));
Edit1.Text:= FirstName;
end;

procedure TForm1.LMDButton2Click(Sender: TObject);
begin
LastName := ArrangeText(IndskrivSaetning('Indskriv Last Name:',Default));
Edit2.Text:= LastName;
end;

procedure TForm1.LMDButton4Click(Sender: TObject);
begin
NickName := ArrangeText(IndskrivSaetning('Indskriv Nick Name:',Default));
Edit3.Text:= NickName;
end;

procedure TForm1.LMDButton5Click(Sender: TObject);
begin
MotherName := ArrangeText(IndskrivSaetning('Indskriv Mother Name:',Default));
Edit4.Text:= MotherName;
end;

procedure TForm1.replayClick(Sender: TObject);
Var
  i: Integer;
begin
RichEdit1.Clear;
For i := 0 to Memo1.lines.count -1 do begin
  Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<First Name>',FirstName, [rfReplaceAll, rfIgnoreCase]);
  Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<Last Name>',LastName, [rfReplaceAll, rfIgnoreCase]);
  Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<Nick Name>',NickName, [rfReplaceAll, rfIgnoreCase]);
  Memo1.lines[i] := StringReplace(Memo1.Lines[i],'<Mother Name>',MotherName, [rfReplaceAll, rfIgnoreCase]);
  RichEdit1.Lines.Add(Memo1.lines[i]);
end;

end;
end.

Hele Projektet kan hentes her: www.sunwind.dk/BogProjekt.zip
Oh Teksten til bogeksempel: www.sunwind.dk/Bogeksempel.txt

Håber du kan se fejlen ved at hente programmet og tekst-filen

Med venlig hilsen
Monie Jacobsen

Med venlig hilsen
Monie Jacobsen
Avatar billede hrc Mester
02. april 2004 - 14:33 #3
Aarrg. Har du ikke hørt om indryk...! Jeg kigger lidt mere på det.
Avatar billede monie Nybegynder
02. april 2004 - 14:39 #4
OK hrc

Uha, Uha!
Håber du har eller kender noget til LMD-komponenten
eller godt kan se brugen af denne komponent.

Mvh
Monie Jacobsen
Avatar billede hrc Mester
02. april 2004 - 15:22 #5
Komponenterne siger mig ikke så meget. Jeg har lagt min egen version af ArrangeTest ved. Den er mindre kompliceret og tager højde for "Bruun-Larsen" situationer (det sidste tilføjede jeg her og er ikke testet).

// Makes "first chars" uppercase
function ArrangeText(const aText : string) : string;
var
  i : Integer;
begin
  Result := AnsiLowerCase(aText);
  for i := 1 to Length(Result) do
    if (i = 1) or ((i > 1) and (aText[i-1] in [' ','-'])) then
      Result[i] := UpCase(Result[i]);
end;


Jeg har kørt din vedlagte tekst og der er ikke noget problem andet, at du skriver "First Name" i programmet og "Fathers Name" i filen. Når det er rettet, så virker det fint hos mig. I øvrigt: eFirstName, eSurname, eNickname, eMothersName nedenfor, er TEdits.

procedure TForm1.btnTestClick(Sender: TObject);
var
  i: integer;
  st : string;
begin
  Memo1.Clear;
  RichEdit1.Lines.Clear;

  Memo1.Lines.LoadFromFile('c:\test.txt');

  for i := 0 to Memo1.lines.count -1 do begin
    st := Memo1.Lines[i];
    st := StringReplace(st,'<First Name>',eFirstName.Text, [rfReplaceAll, rfIgnoreCase]);
    st := StringReplace(st,'<Last Name>',eSurname.Text, [rfReplaceAll, rfIgnoreCase]);
    st := StringReplace(st,'<Nick Name>',eNickname.Text, [rfReplaceAll, rfIgnoreCase]);
    st := StringReplace(st,'<Mother Name>',eMotherName.Text, [rfReplaceAll, rfIgnoreCase]);
    RichEdit1.Lines.Add(st);
  end;
end;


Så til de belærende ord angående din kodning. Der er meget og lære endnu og jeg skriver det kun for at hjælpe:

1. Indryk er til for at gøre teksten mere læselig. Brug det! Så travlt har du heller ikke :-)

2. Globale variable er noget fanden skabte. Lad være med at definere variablene globale såsom: FirstName, LastName, NickName,MotherName, Default : string; Når det er nødvendigt er det et 100% sikkert tegn på at designet er forkert.

3. Giv dog dine komponenter nogle fornuftige navne. Du sparer tid i den sidste ende.

4. Når man programmerer er konsekvens alfa og omega. Det gælder også valg af sprog og variablenevne. Enten holder man sin kodning i dansk eller så vælger man et sprog som alle kan forstå. Engelsk er et godt valg.

5. Det samme gælder den synlige tekst. Det ser ikke pænt ud når du skriver "Indskriv First Name". Skriv "Skriv fornavn:" eller bare, hvis engelsk "First name:".

6. I MDFileOpenEdit1Click tildeler du en værdi til filnavn - men du bruger den ikke til noget. Væk med den slags.

7. Det hedder ikke kællenavn. Mon ikke du mener kælenavn.
Avatar billede monie Nybegynder
02. april 2004 - 16:19 #6
Hej hrc
Lige en slut- kommentar.
Jeg beklager, jeg er lidt ordblind! Men helt i orden med, at gører opmærksom på det.
Så fejlene kan rettes.
Envider mange tak, for din fine kommentar som jeg kan arbejde vider med, selom
der ikke var mange Point, at rytte med.

Med venlig hilse
Monie Jacobsen
Avatar billede hrc Mester
02. april 2004 - 16:51 #7
Har du fået det til at virke? Var det "First Name" kontra "Father Name" der var problemet?

Jeg har stor respekt for den kamp ordblinde har med at sætte tekst på ord (desværre forstår jeg ikke at begrænse mig selv og det kan sikkert være en belastning hver gang jeg smider en kommentar).

Jeg rettede dig fordi det lignede en fejl der godt kunne smutte med i et offentliggjort produkt.

Er ked af at du er i bund med points. Du har vel stadig min email fra dengang du spurgte om ini-filer, ikke? Du er velkommen til at bruge den hvis du har problemer.

P.S. Andre gange retter jeg folk fordi jeg hader/og knapt forstår den SMS-danske dialekt som læres ved mobiltelefonen.
Avatar billede monie Nybegynder
02. april 2004 - 17:48 #8
Hej hrc
Har fået din version til at virke. Det var ordblindheden der drillede.
Men når jeg laver InputBox går det galt. Arbejder med problemmet.

Med venlig hilsen
Monie Jacobsen
Avatar billede monie Nybegynder
02. april 2004 - 17:51 #9
Til hrc
Selvom jeg ikke har flerer Point. Må jeg da godt evt. stille dig spørgamål?
ang. det projekt der her.

Med venlig hilsen
Monie Jacobsen
Avatar billede monie Nybegynder
02. april 2004 - 18:35 #10
Hej hrc

Hvis jeg skriver:
  st := StringReplace(st,'eFirstname',eFirstname, [rfReplaceAll, rfIgnoreCase]);
Så bliver der bare nogen tomme huller, hvor ændringen skulle havde indsat.

Modsat hvis der blev skrevet:
st := StringReplace(st,'<First Name>','eFirstname', [rfReplaceAll, rfIgnoreCase]);
Så bliver eFirstname udskiftet med eFirstname.

Det er alså ved InputBox det går galt et eller andet sted.

Hvorfor bliver variablen Firstname ikke, med et indskrevet navn brugt?
procedure TForm1.LMDButton3Click(Sender: TObject);
var
  Firstname,Default : String;
begin
Firstname := ArrangeText(IndskrivSaetning('Indskriv First name:',Default));
eFirstName.Text:= Firstname;
end;


Her er hele Unit

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, LMDCustomButton, LMDButton, LMDCustomControl,
  LMDCustomPanel, LMDCustomBevelPanel, LMDBaseEdit, LMDCustomEdit,
  LMDCustomBrowseEdit, LMDBrowseEdit, LMDCustomFileEdit, LMDFileOpenEdit,
  ComCtrls, MinUnits;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    LMDButton1: TLMDButton;
    LMDFileOpenEdit1: TLMDFileOpenEdit;
    RichEdit1: TRichEdit;
    replay: TLMDButton;
    LMDButton3: TLMDButton;
    eFirstName: TEdit;
    LMDButton2: TLMDButton;
    eLastname: TEdit;
    LMDButton4: TLMDButton;
    LMDButton5: TLMDButton;
    eNickname: TEdit;
    eMothername: TEdit;
    LMDButton6: TLMDButton;
    eFathersname: TEdit;
    procedure LMDButton1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure LMDFileOpenEdit1Click(Sender: TObject);
    procedure replayClick(Sender: TObject);
    procedure LMDButton3Click(Sender: TObject);
    procedure LMDButton2Click(Sender: TObject);
    procedure LMDButton4Click(Sender: TObject);
    procedure LMDButton5Click(Sender: TObject);
    procedure LMDButton6Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
 
implementation

{$R *.dfm}

Function Rotate(Teksten: String):String;
var
  x: Integer;
  Temp: String;
begin
  Temp:='';
  for x:=length(Teksten) downto 1 do
    Temp:=Temp+Teksten[x];
  Result:=Temp;
end;

function ArrangeText(const aText : string) : string;
var
  i : Integer;
begin
  Result := AnsiLowerCase(aText);
  for i := 1 to Length(Result) do
    if (i = 1) or ((i > 1) and (aText[i-1] in [' ','-'])) then
      Result[i] := UpCase(Result[i]);
end;


procedure TForm1.LMDButton1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
eFirstName.Clear;
eLastname.Clear;
eNickname.Clear;
eMothername.Clear;
eFathersname.Clear;
Memo1.Clear;
RichEdit1.Clear;
end;

procedure TForm1.LMDFileOpenEdit1Click(Sender: TObject);
Var
  filnavn : STRING;
begin
    begin
          //Memo1.Clear;
          Memo1.Lines.LoadFromFile(LMDFileOpenEdit1.Filename);
          filnavn := LMDFileOpenEdit1.Filename;
    end;
end;

procedure TForm1.LMDButton3Click(Sender: TObject);
var
  Firstname,Default : String;
begin
Firstname := ArrangeText(IndskrivSaetning('Indskriv First name:',Default));
eFirstName.Text:= Firstname;
end;

procedure TForm1.LMDButton2Click(Sender: TObject);
var
Lastname,Default : String;
begin
Lastname := ArrangeText(IndskrivSaetning('Indskriv Last name:',Default));
eLastname.Text:= Lastname;
end;

procedure TForm1.LMDButton4Click(Sender: TObject);
var
Nickname,Default : String;
begin
Nickname := ArrangeText(IndskrivSaetning('Indskriv Nick name:',Default));
eNickname.Text:= Nickname;
end;

procedure TForm1.LMDButton6Click(Sender: TObject);
var
Fathersname,Default : String;
begin
  Fathersname := ArrangeText(IndskrivSaetning('Indskriv Fathers name:',Default));
eFathersname.Text:= Fathersname;
end;


procedure TForm1.LMDButton5Click(Sender: TObject);
var
Mothername,Default : String;
begin
Mothername := ArrangeText(IndskrivSaetning('Indskriv Mother name:',Default));
eMothername.Text:= Mothername;
end;

procedure TForm1.replayClick(Sender: TObject);
Var
  i  : integer;
  st : string;
  eFirstname, eLastname, eNickname, eFathersname, eMothername : string;
begin
    //RichEdit1.Lines.Clear;
    for i := 0 to Memo1.lines.count -1 do begin
    st := Memo1.Lines[i];
    st := StringReplace(st,'<First Name>',eFirstname, [rfReplaceAll, rfIgnoreCase]);
    st := StringReplace(st,'<Last Name>',eLastname, [rfReplaceAll, rfIgnoreCase]);
    st := StringReplace(st,'<Nick Name>',eNickname, [rfReplaceAll, rfIgnoreCase]);
    st := StringReplace(st,'<Fathers Name>',eFathersname, [rfReplaceAll, rfIgnoreCase]);
    st := StringReplace(st,'<Mother Name>',eMotherName, [rfReplaceAll, rfIgnoreCase]);
    RichEdit1.Lines.Add(st);
    end;
end;
end.

Håber meget på du vil hjælpe mig!

Med venlig hilsen
Monie Jacobsen
Avatar billede hrc Mester
02. april 2004 - 18:40 #11
Jeg skrev før at eFirstname og de andre, var TEdit-komponenter. Når de starter med et 'e', så fortæller jeg at det er en TEdit klasse. Tilsvarende vil jeg måske have en lvData som så var en TListView. Jeg bruger initialerne i navnet.

Du skal derfor fortsat søge efter '<First Name>'. Jeg brugte bare den værdi som brugeren havde skrevet i eFirstname:

  st := StringReplace(st,'<First Name>',eFirstname.Text, [rfReplaceAll, rfIgnoreCase]);

Bemærk, at jeg har tilføjet .Text efter eFirstname for at få adgang til det som står på linien. Skal gerne sende dig mit minimale eksempel. Har du min email?
Avatar billede monie Nybegynder
03. april 2004 - 07:41 #12
Hej hrc
Ved at tilføjet .Text efter eFirstname som du beskrev, nu virker det fint.
Havde jeg helt overset dette.

Må jeg holde denne tråd igang, for vider, at kunne stille dig spørgamål,
selvfølgelig med Point.
Jeg er nemlig ved, at lave et lille bogprogram hvor den tekst-fil ('c:\test.txt')
vi hente ind skal behandles i bogprogrammet.
Eller vil det være bedere pr. E-mail?
Mine E-mail: mjs at nypost dot dk
Du må gerne sende dit minimale eksempel. Da jeg tror jeg kan lærer meget af det.

Et spørgamål om font-skrifttype-color-størelse indsat i afsnittene.
Kan dette lade sig gørere?

('c:\test.txt')->
Dansk Udgave!

<font-skrifttype-color-størelse> Kan man lave noget med dette ønske?

Der er valgt DanskBabybog.

<Fathers Name> ønskede <Mother Name> tilykke med fødselsdagsbogen i dag.
<Mother Name> var glad og <Nick Name>, som var hans kællenavn.

Med venlig hilsen

<First Name> <Last Name>

***End file

Med venlig hilsen
Monie Jacobsen
Avatar billede hrc Mester
04. april 2004 - 10:37 #13
I TMemo kun for hele teksten, mens TRichEdit fungerer på følgende måde.

I øvrigt er jeg ikke helst sikker på du vælger den bedste løsning hvis du vil parsen en rigtig stor fil. Ved en 10kb stor fil vil programmet være nødt til at læse 40kb fordi det sker hver gang du søger på en ny <>.

En smartere løsning er nok at starte fra en ende af, standse ved '<' og undersøge om efterfølgende var noget der skulle erstattes. Jeg har ikke tid til at fortælle/beskrive denne løsning yderligere grundet travlhed - vil hjælpe hvor det er muligt.

Nedenstående kode sætter nye attributter for tegnene 3 til 6 i en TRichEdit til fonten "Curier New", farven rød og størrelsen 22 pkt.

  RichEdit1.SelStart := 2;
  RichEdit1.SelLength := 4;
  RichEdit1.SelAttributes.Color := clRed;
  RichEdit1.SelAttributes.Name := 'Courier New';
  RichEdit1.SelAttributes.Size := 22;
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester