Skocz do zawartości


[Pascal] Wczystywanie wyrazów z pliku


11 odpowiedzi w tym temacie

#1 Quass1m

    Nowy na forum

  • Użytkownicy
  • 7 Postów:

Napisano nie, 24 kwi 2011 - 13:13

Próbuję napisać program, który wczyta wyrazy z pliku tekstowego i zapisze każdy z nich do tablicy dwuwymiarowej (wiersz, numer wyrazu w wierszu). Nie wiem jaka jest tego przyczyna ale okazało się, że program co każdy wiersz z wyrazami wypisuje pusty wiersz, np. wyraz z 3 pozycji w wierszu nr 3 jest zapisany w tablicy jako b[5,3]. Proszę o poradę jak naprawić program lub o chociaż informację jaka jest przyczyna takiego błędu.

pascal

program slowa;

uses crt;

var x,y,z:longint;
        t:text;
        a:array[1..2000,1..2000] of char;
        b:array[1..200,1..10] of string;
        l,m,n,p:integer;
        zn:char;

begin
     writeln();
     writeln('_________________________________________');
     assign(t, 'F:\lista.txt');

     reset(t);
     m:=0;

     repeat
          inc(m);
          l:=1;
          repeat
               read(t,a[m,l]);
               write(a[m,l]);
               inc(l);
          until eoln(t);

     until eof(t);
     writeln();
     writeln('=========================================');
     writeln();

     for m:=1 to 9 do
          begin
          p:=1;
          for l:=1 to 100 do
          begin
               if a[m,l] <> ' ' then b[m,p]:=b[m,p]+a[m,l] ;
               if a[m,l] = ' ' then
                    begin
                         write(b[m,p],' ');
                         inc(p);
                    end;
         end;
     writeln();

     close(t);

     readkey;

end.

 

 



P.S. Plik tekstowy zawiera 4 wiersze po 5 wyrazów, przykład:
kot dom znak tebafla fasarttt
kwa wak awk kka was
mercury cumrery yrucrem mercyru ymrrcue
asdrr sdfasffa sadsd fasfas alfabet

Użytkownik Integer edytował ten post nie, 24 kwi 2011 - 19:42
Wcięcia


#2 Blind

    Dzień dobry

  • Moderatorzy
  • 1057 Postów:

Napisano nie, 24 kwi 2011 - 13:31

Debuger zna odpowiedź.

#3 Integer

    Pomocna dłoń

  • Moderatorzy
  • 191 Postów:
  • Gadu-Gadu:6888400

Napisano nie, 24 kwi 2011 - 19:55

z grubsza pokolei:
1. Poprawiłem Ci wciecia - prawda ze lepiej to wygląda?
2. Usunłem 1 begina i bodajże 2 endy które były nie potrzebne a zaciemniały strukturę - przynajmniej mnie się tak wydaje
3. Zamiast oddzielania wyrazów w pliku spacją użyj może średnika, będziesz mógł wstawiać wyrażenia kilku wyrazowe
4. Do wczytywania z pliku zwykle używa się pewniejszej struktury

pascal

var Linijka: String;
    While not (Eof (plik))
    begin
         Readln(Linijka);
    end;OP+Zł7Ł9zyX9śzĘvęó{Ź\"(pĘśłŹFWzxkKnŻ*ZąĆqGf\"ŁFVvW#Ś& amp;VvŁ2b33łb33Ć挜w7VVŚW776Śbfw
CłFVŚćĆ2g&VFć7w&\0&Vv\0\0VćCśW&6ŚRć7G&ćv6VGW&&66ĆFVĆWFRśś6vćRćWG'ŚV&ćVvg&vVGW6śśvćRg&vVGW





#4 Integer

    Pomocna dłoń

  • Moderatorzy
  • 191 Postów:
  • Gadu-Gadu:6888400

Napisano nie, 24 kwi 2011 - 20:01

A tak na temat: zrób najpierw samo wpisywanie wyrazu do tabeli
(wykasuj sobie wczytywanie numeru)
i wyświetlaj sobie kolejno
>numer z pętli<, >wyraz wstawiany< i >wyraz z tabeli<
w takich klamerkach >< będziesz widział gdzie Ci się puste wyrazy wstawiają
a jak już to zadziała - rozbuduj program

#5 Stelma

    Starszy bywalec

  • Super użytkownicy
  • 103 Postów:
  • Gadu-Gadu:4588140

Napisano pon, 25 kwi 2011 - 09:58

Popieram Integer'a smile.gif

Dodam od siebie iż po wczytaniu zawartości linijki wystarczy napisać sobie funkcję "explode" która zwróci ci tablice. I po kłopocie. Dzięki temu będziesz mógł użytkownikowi pozwolić zadecydować po czym ma rozbijać plik (domyślnie " ").

Żeby nie było iż marudze to nagłówek :

pascal

 function explode( text : String; explod : Char = ';' ): TLineOP--śjB[HHXY[^H[[

 


#6 Quass1m

    Nowy na forum

  • Użytkownicy
  • 7 Postów:

Napisano pon, 25 kwi 2011 - 15:32

CYTAT(Blind @ nie, 24 kwi 2011 - 14:31) <{POST_SNAPBACK}>
Debuger zna odpowiedź.


Niestey nie byłem w stanie znaleźć tej odpowiedzi...

CYTAT(Integer @ nie, 24 kwi 2011 - 20:55) <{POST_SNAPBACK}>
z grubsza pokolei:
1. Poprawiłem Ci wciecia - prawda ze lepiej to wygląda?
2. Usunłem 1 begina i bodajże 2 endy które były nie potrzebne a zaciemniały strukturę - przynajmniej mnie się tak wydaje
3. Zamiast oddzielania wyrazów w pliku spacją użyj może średnika, będziesz mógł wstawiać wyrażenia kilku wyrazowe
4. Do wczytywania z pliku zwykle używa się pewniejszej struktury
(...)


Aż o 1 end'a za dużo ;)

Spróbowałem wykorzystać twoją strukturę i obliczanie pozycji podziału wyrazów ale niestety nie wiem w jaki sposób miałbym odczytać więcej niż 1 wyraz z wiersza. Dostaję pozycję 1szej spacji lub średnika lecz co potem? W jaki sposób mógłbym znaleźć pozycję kolejnej przerwy między wyrazami?

Cytat

Popieram Integer'a :)

Dodam od siebie iż po wczytaniu zawartości linijki wystarczy napisać sobie funkcję "explode" która zwróci ci tablice. I po kłopocie. Dzięki temu będziesz mógł użytkownikowi pozwolić zadecydować po czym ma rozbijać plik (domyślnie " ").
(...)



Przyznam szczerze że nie mam pojęcia jak miałaby wyglądać taka funkcja explode... Nigdy dotąd się z nią nie spotkałem (na pewno nie w Pascalu).

#7 Stelma

    Starszy bywalec

  • Super użytkownicy
  • 103 Postów:
  • Gadu-Gadu:4588140

Napisano pon, 25 kwi 2011 - 16:00

Mam dobry humor bo święta.

Cyrkiel na forum ks-expert.pl napisał
pascal


PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
 

 


Ja dodam I już masz explode, wadą tego rozwiązania jest to iż trzeba używać TStringList zamiast tablicy. Jeżeli jednak chcesz koniecznie tablice to musisz Przeszukiwać ciąg znaków w poszukiwaniu danego znaku przyda ci się tutaj (nie wiem czy w pascalu jest):

delphi


PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
 

 


#8 Integer

    Pomocna dłoń

  • Moderatorzy
  • 191 Postów:
  • Gadu-Gadu:6888400

Napisano pon, 25 kwi 2011 - 17:22

Quass1m co do tego enda to mniej więcej wygląda to tak ze jak od początku uczysz się bałaganu to po prostu ciężko Ci ogarnąć to co piszesz.
W tych konkretnych przypadkach end i begin nie przeszkadzały, ale jeśli się tak pomylisz przy warunkach lub w pętlach to taki end może Ci strasznie napsioczyć, i będziesz godzinami szukał błędu dlaczego ci "coś" wyskoczyło albo nie wyskoczyło.

No i teraz zauważyłem dopiero bo Stelma wstawił procki z Delphi, dodaj w temacie [Pascal] lub [Delphi] tak dla pewności wink.gif

funkcja Pos zawsze zwraca pozycję pierwszego szukanego znaku w springu więc jak masz wyrazy w stringu:
s:= 'kot dom znak tebafla fasarttt' to teraz musisz:
1. zdjąć pierwszy wyraz 'kot' i zapamiętac go w tabeli
2. skasować z S ciąg znaków 'kot ' - spacje na końcu też
3. i ponieważ to się dzieje w pętli na nowo szukać spacji i kolejnego wyrazu...

Proponuję Ci zrobić na początek - chociaż może Ci się wydać lekko sadystyczne ale każdemu bym to doradził, zrobić trzy malutkie programiki z zastosowaniem Pos, Copy, i Delete w odniesieniu do stringów będzie tam 6 linijek na krzyż ale przynajmniej będziesz wiedział co one robią i jak działają.
Pamiętaj o wyświetlaniu na końcu stanu każdego stringa i zmiennej, będziesz widział co się dzieje.

A jeśli nie jesteś pewny to skopiuj z pomocy przykłady z ich użyciem żeby nie było pomyłki.

#9 Stelma

    Starszy bywalec

  • Super użytkownicy
  • 103 Postów:
  • Gadu-Gadu:4588140

Napisano pon, 25 kwi 2011 - 18:37

@Integer
Z tym tagiem to moja wina. Choć przyznam że w szkole jak miałem zajęcia z pascala to i tak sobie pisałem w D7 i mogłem używać funkcji z tego języka nauczyciele rzadko się czepiają jeżeli coś się kompiluje...


@Topic
Ja zawsze powtarzam iż w programowaniu można problemy rozwiązać na wiele sposobów. (Ten integer'a z posem, copy, delete lepszy).

pascal


var
 Ret : array [1..100] of string;
 i, j : Integer;
 explod : Char;

explod = ';';
j := 1;
for i := 1 to Count( Text ) do
 begin
 
  if( Text[i] != explod ) then
   begin
     Ret[j][i] := Text[i];
   end else inc(j);

 end;

 

 



Ps autorze wysil komórki jeżeli nie znasz funkcji to oznacza że trzeba ją znaleźć / napisać własną.

#10 Integer

    Pomocna dłoń

  • Moderatorzy
  • 191 Postów:
  • Gadu-Gadu:6888400

Napisano pon, 25 kwi 2011 - 20:14

Stelma - ale ja nie mówiłem ze Twój sposób jest nie na miejscu, tu na forum pasuje wszystko byle na temat, zawsze komuś szersze myślenie się przyda, bo my tu pokazujemy sposoby a nie podajemy gotowce. A [Pascal] w temacie sam wstawię, ale żeby mi to było przed ostatni raz wink.gif

#11 Quass1m

    Nowy na forum

  • Użytkownicy
  • 7 Postów:

Napisano pon, 25 kwi 2011 - 21:51

@Integer
Nie pomyślałem o takim sposobie. Myślę że teraz wyjdzie bez problemu.

@Stelma
Na TYM forum nie znalazłem żadnego explode w dziale Pascal. Niestety też ciężko byłoby mi napisać algorytm o którym nic nie wiem...


Co prawda mój pierwszy sposób teraz wydaje mi się zdecydowanie najprostszy ze wszystkich, ale skoro nie działa idealnie to oczywiście będę dalej kombinował aż program zadziała poprawnie. Dzięki za pomocne rady.

#12 Quass1m

    Nowy na forum

  • Użytkownicy
  • 7 Postów:

Napisano pon, 25 kwi 2011 - 22:52

Wszystko działa tak jak powinno. Ostateczny kod wygląda tak:
pascal

program wyrazy;

uses crt;

var  x,y,m,p,n,i:integer;
     t:text;
     linijka,wyr,cz:string;
     wyraz:array[1..200,1..20] of string;

begin
     clrscr;
     writeln();
     writeln('_________________________________________');
     assign(t, 'F:\lista.txt');

     reset(t);

     m:=0;
      While not (Eof (t)) do

       begin
             Readln(t, Linijka);
             inc(m);
             p:=1;

               repeat

                 I:= Pos(' ',Linijka);
                 wyr:=cz;
                 n:=1;

                 if I>1 then
                         begin
                                repeat
                                wyr:=wyr + Linijka[n];
                                inc(n);
                                until n=I;

                             wyraz[m,p]:=wyr;
                             writeln('Wiersz - ',m, ', Pozycja - ',p, ', = ',wyr);
                             inc(p);

                         end;

                 delete(Linijka, 1, I);

               until p=6;
       end;

     writeln();
     writeln('=========================================');
     writeln();
     writeln('Podaj wspolrzedne wyrazu');
     read(x);
     read(y);
     writeln(wyraz[x,y]);
     close(t);

     readkey;

end.