Tablica wariantowa zawierająca String i Real

0

Potrzebna mi dwuwymiarowa tablica, do której mógłbym wrzucić z pliku tekstowego najpierw wartość String, potem trzy wartości Real. Mam kłopot jak zmusić Delphi żeby skończyła wczytywać wartość String na pierwszym napotkanym tabulatorze, a następne trzy wartości wczytała jako Real. Waszym zdaniem należy bawić się z tablicą wariantową czy kombinować z tablicami typu String i Real?
Przykładowa linijka z pliku tekstowego wygląda tak:

Coś 123.45 6.78901 -12.345

Oczywiście zamiast spacji mają być tabulatory :-) Warto by było, żeby program działał niezależnie od ilości znaków w zmiennej String i ilości cyfr przed i po przecinku w zmiennych Real.

Będę wdzięczny za pomoc.

0

Eh, leniuchy, leniuchy - co się z tymi pytającymi tutaj dzieje, nic nie kobminują samodzielnie - szkoda, bo to
żadna przyjemność dostać gotowca i nic się nie nauczyć. Ale niech będzie, w końcu ja na tym forum jestem w
zasadzie niemal etatowym (tylko że nikt nie płaci) pomagaczem leniwym pytającym z banalnymi problemami.
Tak więc ja bym te linijkę w pliku rozbił tak jak poniżej funkcją Explode, która jak się umiejętnie googluje - to
na jednym forum się znajdzie. Można też to było zrobić przy użyciu Delete oraz Pos, ale tak jak pokazałem, to
chyba jest najlepiej. Zawartość ListBoxa wczytałem sobie z pliku który zawierał linijkę jaką podałeś, oczywiście
oddzieloną tabulatorami. U mnie jest to tylko jedna linijka, dlatego tablica ma też jeden element, ale pętlę no i
inne rzeczy to już sobie dopasujesz. StringReplace jest po to by uniknąć problemów, bo u mnie na przykład na
XP Home SP 2 domyślnym separatorem dziesiętnym jest przecinek, a nie kropka. Dlatego zamieniam aby nie
wyskoczył wyjątek. Typ rekordowy tablicy chyba też dobrze zadeklarowałem, bo o takie coś Ci chyba chodzi?

function Explode(Str : string; Separator : string) : TStringList;
var
  X : Integer;
begin
  Result := TStringList.Create;
  X := Pos(Separator, Str);
  while X > 0 do
  begin
    Result.Add(Copy(Str, 1, X - 1));
    if X <= Length(Str) then
    begin
      Str := Copy(Str, X + Length(Separator), Length(Str));
    end;
    X := Pos(Separator, Str);
  end;
  if (Length(Str) > 0) then
  begin
    Result.Add(Str);
  end;
end;

type
  FourElementsArray = record
    S : string;
    R1, R2, R3 : Real;
  end;

procedure TForm1.Button1Click(Sender : TObject);
var
  S : string;
  I, J : integer;
  SL : TStringList;
  Arr : array[0..0] of FourElementsArray;
begin
  SL := TStringList.Create;
  for I := Low(Arr) to High(Arr) do
  begin
    SL.Clear;
    SL := Explode(ListBox1.Items[I], #9);
    Arr[I].S := SL[0];
    for J := 1 to 3 do
    begin
      S := SL[J];
      if Pos('.', S) > 0 then
      begin
        S := StringReplace(S, '.', DecimalSeparator, [rfReplaceAll]);
      end
      else
        if Pos(',', S) > 0 then
        begin
          S := StringReplace(S, ',', DecimalSeparator, [rfReplaceAll]);
        end;
      SL[J] := S;
    end;
    Arr[I].R1 := StrToFloat(SL[1]);
    Arr[I].R2 := StrToFloat(SL[2]);
    Arr[I].R3 := StrToFloat(SL[3]);
  end;
  SL.Free;
  // Dla sprawdzenia...
  Edit1.Text := Arr[0].S;
  Edit2.Text := FloatTOStr(Arr[0].R1);
  Edit3.Text := FloatTOStr(Arr[0].R2);
  Edit4.Text := FloatTOStr(Arr[0].R3);
end;
0

A co to takiego ?

Arr : array[0..0] of FourElementsArray;
0

A przepraszam, teraz doczytałem - tablica miała być dwuwymiarowa, ale jeśli oba wymiary mają zawierać
takiego samego typu dane lub ewentualnie inaczej, to myślę że pytający już poznał ideę i da sobie radę, o
ile o to Tobie Opi chodziło. A jak nie to popraw mnie proszę i podaj lepsze rozwiązanie dla 2ch wymiarów.
Bo jęzeli chodzi o nazewnictwo to w symie powinno być zamiast FourElementsArray np FourElementsRecord.
Btw, widzę że nie tylko ja siedze po nocach i czytam forum :) Ale pewnie Ty siedzisz, bo weekend wolny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1