Strona g│≤wna

 

ZastΩpowanie wyraz≤w

Pewnie my╢la│e╢ kiedy╢ jak to by by│o fajnie napisaµ program, kt≤ry z│e wyrazy zastΩpowa│ by dobrymi. Np. zast▒piµ wyraz "sie" na "siΩ". Program bΩdzie siΩ opiera│ na dw≤ch plikach tekstowych, kt≤re zawieraµ bΩd▒ s│owa z│e - do zast▒pienia, a w drugim pliku bΩd▒ siΩ znajdywaµ pliki, kt≤re zast▒pi▒ z│e wyrazy. 

Wszystko bΩdzie siΩ opieraµ na module "WordFrm" i na klasie w▒tkowej: 

 TFind = class(TThread)
  private
    FFindText : String;
    FGoodText : String;
    FBadWord : TStrings;
    FGoodWord : TStrings;
  protected
    procedure Execute; override;
    procedure GiveAnswer; 
  public
    constructor Create; 
    destructor Destroy; override;
  end;

Podstawow▒ konstrukcj▒ s▒ dwie zmienne - "FBadWord" i "FGoodWord". Obie te zmienne s▒ typu "TStrings", kt≤re zawieraj▒ listΩ z│ych i dobrych plik≤w. Lista ta │adowana jest z plik≤w tekstowych. W sekcji "protected" znajduje siΩ procedura "GiveAnswer", kt≤ra wy╢wietla rezultat na formie, a konkretnie na komponencie RichEdit. 
G│≤wny w▒tek to nastΩpuj▒cy kod:

Listing 7.1


procedure TFind.Execute;
var
  TF : TextFile;
  BadWord, GoodWord : String;
  Count : Integer; // ilosc slow, ktore znajduja sie w pliku

{  Laduje wyrazy z plikow }
  procedure LoadFile;
  begin
    if not FileExists(WORDS) or not FileExists(GOOD) then
      raise ENoFile.Create(Concat('Brak pliku: ', WORDS, ' lub: ', GOOD)) else

    AssignFile(TF, WORDS);
    Reset(TF);  // otworz plik

    while not Eof(TF) do
    begin
      Readln(TF, BadWord);
      FBadWord.Add(BadWord); // wczytaj zawartosc do zmiennej
    end;
    CloseFile(TF);    // zamknij plik

    AssignFile(TF, GOOD);  // otworz plik drugi
    Reset(TF);

    while not Eof(TF) do
    begin
      Readln(TF, GoodWord);
      FGoodWord.Add(GoodWord); // wczytaj zawartosc do zmiennej
    end;

    CloseFile(TF);
  end;

begin
  FreeOnTerminate := True; // zkoncz watek przy zakonczeniu procrury
  LoadFile;  // wywolaj procedure
{
  tutaj nastepuje sprawdzenie wsystkich wyrazow znajdujacych sie w pliku
  tekstowym i porowanie ich z tym co znajduje sie w zawartosci RichEdir'a.
}

  Count := 0; // wyzeruj licznik...

  repeat // petelka
{
   Do zmiennych zostaje przypisana wartosc z innych zmiennych typu TStrings.
   Wyraz, ktory zostaje przypisany okreslany jest przez licznik - Count.
}
    FFindText := FBadWord.Strings[Count];
    FGoodText := FGoodWord.Strings[Count];

    (GiveAnswer); // wywolaj procedure

    Inc(Count); // zwieksz licznik o jeden

  until Count > FBadWord.Count;
end;

Jak widzisz jedna procedura - LoadFile zawarta jest w drugiej - w w▒tku. Procedura ta powoduje │adowanie tre╢ci pliku tekstowego do zmiennych. 
NastΩpnie zmienna "Count" zostaje zerowana i wykonywana zostaje pΩtelka maj▒ca na celu pobranie za ka┐dym razem wyrazu ze zmiennej i wykonywanie procedury "GiveAnswer", kt≤ra ma za zadanie szukane s│owo ( z│e s│owo ) zast▒piµ dobrym. Oto ta procedura: 

Listing 7.2


procedure TFind.GiveAnswer;
var
  SelPos : Integer;
begin
{ Procedura zastepuje wyraz do zastapienia nowym }
  with MainForm.RichEdit do
  begin
    SelPos := Pos(FFindText, Lines.Text); // znajdz szukany wyraz
    if SelPos > 0 then
    begin
      SelStart := SelPos -1;
      SelLength := Length(FFindText); 
      SelText := FGoodText;  //... i zastap nowym
    end else Exit; // jezeli nic nie znajdziesz - anuluj...
  end;
end;

Ta procedura znajduje s│owo w komponencie "RichEdit", a nastΩpnie znalezione s│owo zast▒pnie dobrym. 

Oto ca│y kod modu│u:

Listing 7.3


(****************************************************************)
(*                                                              *)
(*                 Word Unit fof Change Words programme         *)
(*       Copyright (c) 2001 by Service for programmers          *)
(*            Build:  14.04.2001  -  Adam Boduch                *)
(*              HTTP://WWW.PROGRAMOWANIE.OF.PL                  *)
(*    E - mail: boduch@poland.com                               *)
(*                                                              *)
(****************************************************************)

unit WordFrm;

interface

uses
  Classes, SysUtils, Graphics;

const
{
  Stale przechowuja pliki, w ktorych znajduja sie slowa - do zmiany i
  slowa, ktore nalezy zmienic.
}
  WORDS = 'Words.txt';
  GOOD = 'Good.txt';

type
  ENoFile = class(Exception); // wyjatek wystapi gdy pliku na dysku nie bedzie

  TFind = class(TThread)
  private
    FFindText : String;
    FGoodText : String;
    FBadWord : TStrings;
    FGoodWord : TStrings;
  protected
    procedure Execute; override;
    procedure GiveAnswer; 
  public
    constructor Create; 
    destructor Destroy; override;
  end;

implementation

uses MainFrm;

constructor TFind.Create;
begin
  inherited Create(FALSE);
    FBadWord := TStringList.Create; // utworz zmienne
    FGoodWord := TStringList.Create;
end;

destructor TFind.Destroy;
begin
  FBadWord.Free;
  FGoodWord.Free;  // zwolnij zmienne

  inherited;
end;

procedure TFind.Execute;
var
  TF : TextFile;
  BadWord, GoodWord : String;
  Count : Integer; // ilosc slow, ktore znajduja sie w pliku

{  Laduje wyrazy z plikow }
  procedure LoadFile;
  begin
    if not FileExists(WORDS) or not FileExists(GOOD) then
      raise ENoFile.Create(Concat('Brak pliku: ', WORDS, ' lub: ', GOOD)) else

    AssignFile(TF, WORDS);
    Reset(TF);  // otworz plik

    while not Eof(TF) do
    begin
      Readln(TF, BadWord);
      FBadWord.Add(BadWord); // wczytaj zawartosc do zmiennej
    end;
    AssignFile(TF, GOOD);  // otworz plik drugi
    Reset(TF);

    while not Eof(TF) do
    begin
      Readln(TF, GoodWord);
      FGoodWord.Add(GoodWord); // wczytaj zawartosc do zmiennej
    end;

    CloseFile(TF);
  end;

begin
  FreeOnTerminate := True; // zkoncz watek przy zakonczeniu procrury
  LoadFile;  // wywolaj procedure
{
  tutaj nastepuje sprawdzenie wsystkich wyrazow znajdujacych sie w pliku
  tekstowym i porowanie ich z tym co znajduje sie w zawartosci RichEdir'a.
}

  Count := 0; // wyzeruj licznik...

  repeat // petelka
{
   Do zmiennych zostaje przypisana wartosc z innych zmiennych typu TStrings.
   Wyraz, ktory zostaje przypisany okreslany jest przez licznik - Count.
}
    FFindText := FBadWord.Strings[Count];
    FGoodText := FGoodWord.Strings[Count];

    (GiveAnswer); // wywolaj procedure

    Inc(Count); // zwieksz licznik o jeden

  until Count > FBadWord.Count;
end;


procedure TFind.GiveAnswer;
var
  SelPos : Integer;
begin
{ Procedura zastepuje wyraz do zastapienia nowym }
  with MainForm.RichEdit do
  begin
    SelPos := Pos(FFindText, Lines.Text); // znajdz szukany wyraz
    if SelPos > 0 then
    begin
      SelStart := SelPos -1;
      SelLength := Length(FFindText);  // zaznacz go...
      SelText := FGoodText;  //... i zastap nowym
    end else Exit; // jezeli nic nie znajdziesz - anuluj...
  end;
end;

end.

Polecam ╢ci▒gniΩcie sobie ca│ego programu ( jego kodu ╝r≤d│owego ).

Przydatne linki:

  • W▒tki - artyku│ o tym co to s▒ w▒tki;
  • Klasy - budowa klas;

Replace.zip ( 3 kB ) - kod ╝r≤d│owy prezentowanego tu programu;

Adam Boduch