Programowanie w języku Delphi » Gotowce

Autozastępowanie

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:

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:

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:

(****************************************************************)
(*                                                              *)
(*                 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: [email protected]                               *)
(*                                                              *)
(****************************************************************)
 
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.