Newsgroup: it.comp.lang.delphi
Titolo: SubString in riga di testo

Ho la necessità di estrarre delle substring (sempre 4 e separate ognuna da
uno spazio) da ogni riga di un file di testo.
Uso readln anzichè caricare i files in memoria perchè alcuni potrebbero
essere molto grandi.
Questo è il codice adattato:
procedure TForm1.Button1Click(Sender: TObject);
var
a : string;
i, m, k : integer;
myS : array[0..4] of string;
begin
  a := edit1.Text; // riga che leggo da file, uso TEdit per comodità
  for k := 0 to 3 do
  begin
  m := length(a);
  for i := 0 to m-1 do
  begin
    if a[i] = ' ' then
      begin
        myS[k] := copy(a, 0, i-1);
        a := copy(a, i+1, m);
        break;
      end; // end if a[i]
  end; // end for i
  end; // end for k
  myS[k] := a;
end;
Quello che vorrei chiedervi: conoscete qualche routine alternativa più
performante?
Grazie
Valter

 performante?
Hai provato con ExtractStrings della unit Classes?
Estratto dall'help:
"Fills a string list with substrings parsed from a delimited list.
[...]
function ExtractStrings(Separators, WhiteSpace: TSysCharSet;
  Content: PChar; Strings: TStrings): Integer;"
---
Ryo GQI 

 Hai provato con ExtractStrings della unit Classes?
No, ora gli do un'occhiata...
Grazie
Valter

performante?
type
  TCharSet = set of Char;
  TStringTokenizer = class
  private
    FString: string;
  public
    procedure Tokenize(const AString: string; ADelimiters: TCharSet;
AStrings: TStrings);
  end;
{ TStringTokenizer }
procedure TStringTokenizer.Tokenize;
var
  I: Integer;
  L: Integer;
  S: String;
  function GetNextString: string;
  begin
    Result := '';
    while (I<=L) and (AString[I] in ADelimiters) do
      Inc(I);
    while (I<=L) and (not (AString[I] in ADelimiters)) do
    begin
      Result := Result + AString[I];
      Inc(I);
    end
  end;
begin
  L := Length(AString);
  I := 1;
  while (I<=L) do
  begin
    S := GetNextString;
    if S <> '' then
      AStrings.Add(S);
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  with TStringTOkenizer.Create do
    Tokenize('oggi vado al mare, mi abbronzo, mi sbronzo e vado a
zonzo',
             [' ', ','],
             Memo1.Lines);
end;

 { TStringTokenizer }
Grazie, mi faccio due prove di lettura su qualche centinaio di file letti
sequenzialmente e cronometro i tempi per entrambe le routine...poi ti so
dire quanto si guadagna
Ciao
Valter

 dire quanto si guadagna
nessuna differenza...i tempi sono esattamente gli stessi...
ho processato pochi files con molte righe e numerosi files con poche righe
ma non ho riscontrato nè guadagni ne perdite con entrambe le routine.
Il punto di forza di quella suggerita da Andrea è che non richiede di
conoscere il numero di substring presenti nella riga come al contrario esige
la mia (che cmq potrebbe essere adattata con una verifica di fine riga).
Grazie per i vostri suggerimenti.
Ciao
Valter

 ha scritto nel messaggio 
news:Zp8Zf.54167$nz4....@tornado.fastwebnet.it...

Non so se sia piu' performante ma farei cosi':
s: String; arrS: Array[0..3] of String;
n, Count: Integer;
....
Count:=-1;
s:=Trim(Edit1.Text);
Repeat
    Inc(Count);
    n:=Pos(s, ' ');
    if Count<=2 then
        begin
        if n>0 then
            begin
            arrS[Count]:=Copy(s,1,n-1)
            delete(s,1,n);
            end
        else
            // manca qualche stringa
            break;
        end
    else
        arrS[3]:=s;
Until Count=3;
Giorgio

 Non so se sia piu' performante ma farei cosi':
[...]
Giusto per conoscenza: stessi tempi...
si tratta di scegliere la routine che "piace di piů" o che meglio si adatta
al proprio codice
Probabilmente lavorando sulle stringhe č difficile ottenere meglio di cosě
Grazie
Ciao
Valter