wczytywanie danych- kilka stringów w jednej linii

0

witam, mój problem jest następujący:

dane mam na wejściu n linijek. na początku każdej linii jest cyfra, oznaczająca ile słów (stringów, które chcę wydzielić) znajduje się w danej linii.
przykładowe wejście.

4 szkola osa pies Jasio 

w tym miejscu chciałbym wczytać do tablicy [1..4] stringów, 4 stringi, w taki sposób, aby t[1]='szkola', t[2]='osa', itd..

gdy próbuję zrobić tak:

var i,m: integer; t: array[1..10] of string;
begin
read(m);
for i:=1 to m do read(t[i]);
end.

indeks pierwszy tablicy t będzie zawierał całego stringa ze spacjami, natomiast pozostałe 3 będą puste.

wiem, że można skanować kolejne chary w tym całym stringu i przerywać wczytywanie danego słowa gdy natkniemy się na spację, i wczytywanie kolejnego słowa rozpoczynać tuż po spacji - ale czy da się to zrobić jakoś bardziej przyzwoicie? tzn, pomieszać coś, albo wczytywać inaczej (?), żeby jakimś sposobem znak spacji ograniczał stringa? (tak jak jest w przypadku danych liczbowych - z linii 10 20 30 40 można spokojnie bez czarów wczytać 4 integery osobno)

1

Patryk założył, że można użyć wyrażeń regularnych i poczytać o Pos,
bo PosEx chyba w Pascalu nie ma. A skąd założyłem, że za pewnie tu
pytającemu chodzi o Pascala, a no dlatego, że koniecznie chce słowa,
wyodrębnione z linii w pliku tekstowym przechowywać tylko w tablicy
o ograniczonej liczbie elementów. Ech pytaczu leniwy. Miałem już tak
nie pisać, ale masz kod poniżej - się nic nie nauczysz, a owe zadanie
jakie dostałeś jest banalne, jak taki łosiek jak ja sobie dal radę, to w
góra godzinę z testami byś to sam napisał, tylko trzeba chcieć - lecz
wiadomo jest forum, jest olesio, można olać zaliczenia oraz nauke, a
najlepiej zostać ninją. I nie pisz proszę, że wykładowca nic nie uczył.

program gles;

const
  AFileName = 'D:\data.txt';
  LeftChars : array[boolean] of string = (#32, #32#32);
type
  TStringArray10 = array[1..10] of string;
var
  TF : Text;
  S, Line : string;
  I, Code : integer;
  Arr : TStringArray10;

procedure Explode(Str : string; Separator : string; var AnArr : TStringArray10);
var
  I, X : integer;
begin
  I := Low(AnArr);
  X := Pos(Separator, Str);
  while X > 0 do
  begin
    if I <= High(AnArr) then
    begin
      AnArr[I] := Copy(Str, 1, X - 1);
      I := I + 1;
    end;
    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
    if I <= High(AnArr) then
    begin
      AnArr[I] := Str;
    end;
  end;
end;

begin
  Assign(TF, AFileName);
{$I-}
  Reset(TF);
{$I+}
  if IOResult <> 0 then
  begin
    Writeln('Nie mozna wczytac lub brak pliku: ', AFileName, '!');
  end
  else
  begin
    while not EOF(TF) do
    begin
      for I := Low(Arr) to High(Arr) do
      begin
        Arr[I] := '';
      end;
      Readln(TF, Line);
      S := Copy(Line, 1, Pos(#32, Line) - 1);
      Val(S, I, Code);
      if (Code = 0) and (I <= High(Arr)) then
      begin
        S := Copy(Line, Pos(#32, Line) + 1, MaxInt);
        Explode(S, #32, Arr);
        for I := Low(Arr) to High(Arr) do
        begin
          if Arr[I] <> '' then
          begin
            Writeln(LeftChars[I < High(Arr)], I, ': ', Arr[I]);
          end
          else
          begin
            Break;
          end;
        end;
        Writeln;
      end;
    end;
    Close(TF);
  end;
  Readln;
end.
0

Wow, wielkie dzięki za trud :P nie jestem jeszcze studentem, póki co piszę 'rekreacyjnie' i przygotowuję się do sparingów programistycznych. po prostu chciałem się dowiedzieć, czy można to zrobić bez komplikowania sprawy - tzn, tak prosto, jak prosto wczytuje się liczby z jednej linii.

dotychczas, gdy miałem taką sytuację, robiłem:

var
i,m: integer;
t: array[1..10] of string;
pom: char;
cale_slowo: boolean;

begin
read(m); read(pom); //spacja
for i:=1 to m do t[i]:='';
i:=0;
while i<m do
begin
        inc(i);
        if i=m then readln(t[i]) else
        begin
                cale_slowo:=false;
                while not cale_slowo do
                begin
                        read(pom);
                        if pom<>' ' then t[i]:=t[i]+pom else cale_slowo:=true;
                end;
        end;
end;

for i:=1 to m do writeln(t[i]);
readln;
end.

co do Twojego kodu - to może to zabrzmi zaskakująco, ale rozumiem, na jakiej zasadzie działa ^^ ale chyba zostanę przy swojej metodzie. Dzięki :)

0

Ok, rób jak uważasz, ja kiedyś taką implementację ale funkcji nie procedury - Explode znalazłem na
jakimś polskim forum, ale dla Delphi i TStringList jako wyniku. No i czasami staram się ją stosować.

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