Mam problem. Chciałbym, żeby ze stringawartość1|wartość2|wartość3
rozdzielało mi wartości do 3 stringów: w1, w2 i w2. Kiedyś wiedziałem, co to za funkcja, ale pamięć mnie zawodzi. Pomóżcie.
Pos, Copy, Delete...
Copy(S1, n1, n2) gdzie S1 to string n1 to pozycja startu, n2 liczba iteracji.
Owe słowa są odzielone znakiem | (zakładam) to użyj funkcji Pos która zwróci indeksy ich wystąpień. Wtedy dopiero pos. Chyba, że słowa mają dokładnie tą samą długość.
procedure rozdziel(tekst: String; znak: Char; var Buffer: TStringList);
begin
Buffer.Clear;
while Pos(znak, tekst) <> 0 do
begin
Buffer.Add(Copy(tekst, 1, Pos(znak, tekst)-1));
tekst := Copy(tekst, Pos(znak, tekst) +1, Length(tekst) - Pos(znak, tekst));
end;
if Length(tekst)= 1 then
Buffer.Add(tekst);
Buffer.Add(Copy(tekst, 1, Pos(znak, tekst)-1));
end;
kiedyś znalazłem ten kod... powinno zadziałać.. gdzieś to kiedyś znalazłem na 4p ale nie pamiętam gdzie..
Nie do końca o to mi chodzi. Długość stringów pomiędzy znakiem "|" nie jest ustalona. Tutaj chodzi tylko o to, żeby z zapisu edit1|edit2|edit3 itd. dać te wartości do editów. Tylko.
Witam. Napisałem na szybko procedurkę, która wykona owo zadanie. Nie miałem czasu na zrobienie uniwersalnej, tak więc jest ściśle dopasowana do potrzeb. Niewielka modyfikacja i będzie ok. Liczy się idea.
Przepraszam za nieco zagmatwany zapis, ale naprawdę nie miałem więcej czasu. Poniżej zamieszczam kod:
procedure ExtractString(const s :string; var s1, s2, s3: string);
var
p : array[1..2] of byte;
i, j :byte;
begin
j := 0;
for i := 1 to Length(s) do
if s[i] = '|' then
begin
Inc(j);
p[j] := i;
end;
s1 := Copy(s, 1, p[1]-1);
s2 := Copy(s, p[1]+1, p[2]-p[1]-1);
s3 := Copy(s, p[2]+1, Length(s)-p[2]);
end;
Inny sposób to przy pomocy TStringList.
Robione na szybko bez kompilatora:
var
s: TStringList;
begin
s := TStringList.Create;
s.Delimiter := '|';
s.DelimitedText := 'blablabla|ithirh|123|abc';
s.Free;
end;
W ten sposób otrzymasz tablice ciągów (s.Strings[n]) z rozdzielonymi wartościami.
Przykład na podstawie autora: pq Tutaj Oryginał.
uses
StrUtils;
function RozdzielString(const AString: string; const Separator:Char; SList:TStringList): integer;
var
CurPos, PrevPos: integer;
Tmp: string;
begin
Result := 0;
CurPos := 0;
repeat
PrevPos := Succ(CurPos);
CurPos := PosEx(Separator,AString,PrevPos);
inc(Result);
if SList<> nil then
begin
if CurPos = 0 then Tmp := Copy(AString,PrevPos,Length(AString))
else Tmp := Copy(AString,PrevPos,CurPos-PrevPos);
SList.Add(Tmp);
end;
until CurPos = 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Lista: TStringList;
begin
Lista := TStringList.Create;
RozdzielString('|aaa|bbb|ccc|', '|', Lista);
Memo1.Lines.Assign(Lista);
Lista.Free;
end;
Dziękując za zacytowanie pozwolę sobie zauważyć, że istnieje też wbudowana funkcja ExtractStrings, której działanie jest podobne do mojej, z tym wyjątkiem, że jeśli string do rozdzielenia zaczyna się separatorem, wówczas ExtractStrings pomija ten separator, zaś moja funkcja zwraca pusty string. Ponadto ExtractStrings ma inne ciekawe własności: np pozwala na użycie kilku separatorów lub kilku whitespaces (znaków pomijanych).