ReadCustom() funktiolle annetaan string syötteenä teksti, erotin (joka voi olla ihan mikä vaan, kuinka monta kertaa peräkkäin tahansa sekä missä tahansa välissä) sekä taulukot johon tekstin tiedot erotellaan ja vielä lisäksi taulukko jossa on tieto kunkin alkion tyypistä. Mikäli tyyppi-lista on lyhyempi kuin data-listan pituus, käydään tyyppi-listaa läpi useamman kerran. Eli [crString,crInt] taulukkoa voisi käyttää lukemaan monia peräkkäisiä string,int jaksoja.
type TCustomRead = (crString, crInt, crSingle, crDouble, crByte, crWord, crShortInt, crSmallInt, crCardinal, crBool, crInt64); { ... } function ReadCustom(const s,separator: string; const arr: array of pointer; const arrt: array of TCustomRead): integer; var p,arrtl: integer; cur: string; defaultStr: boolean; procedure SetValue; begin if arr[p]=nil then exit; if defaultStr then string(arr[p]^):=cur else case arrt[p mod arrtl] of crString: string(arr[p]^):=cur; crInt: integer(arr[p]^):=strtointdef(cur,0); crSingle: single(arr[p]^):=strtofloat(cur); crDouble: double(arr[p]^):=strtofloat(cur); crByte: byte(arr[p]^):=strtointdef(cur,0); crWord: word(arr[p]^):=strtointdef(cur,0); crShortInt: shortint(arr[p]^):=strtointdef(cur,0); crSmallInt: smallint(arr[p]^):=strtointdef(cur,0); crCardinal: cardinal(arr[p]^):=strtointdef(cur,0); crBool: boolean(arr[p]^):=(cur<>'0') and (lowercase(cur)<>'false'); crInt64: int64(arr[p]^):=strtoint(cur); end; end; var ha,i,l: integer; c,cs: string; begin ha:=high(arr); if ha<1 then begin result:=0; exit; end; defaultStr:=high(arrt)<1; arrtl:=length(arrt); p:=0; l:=length(separator); i:=1; cur:=''; while i<=length(s) do begin c:=copy(s,i,1); cs:=copy(s,i,l); if cs=separator then begin if cur<>'' then begin SetValue; cur:=''; inc(p); if p>ha then break; end; inc(i,l-1); end else cur:=cur+c; inc(i); end; if cur<>'' then begin SetValue; inc(p); end; result:=p; end;
Testiohjelma
procedure TForm1.FormCreate(Sender: TObject); var i,i2: integer; si: single; s,text,text2: string; begin s:='testi--900----8.514--testi2--200'; // Taulukkoa ei tarvitse luoda lennosta mutta tämäkin // on mahdollista ja usein ehkä helpompaa ReadCustom(s,'--',[@text,@i,@si,@text2,@i2], [crString,crInt,crSingle]); edit1.Text:=format('%s,%d,%f,%s,%d',[text,i,si,text2,i2]); end;
Palauttaa:
testi,900,8.51,testi2,200
Aihe on jo aika vanha, joten et voi enää vastata siihen.