[Pascal] tablica z pojedynczymi znakami


(K Ilak) #1

Witam,

chcę napisac program, który będzie zamieniał litery na cyfry i znaki, problem jest jeden:

chce, żeby użytk. wpisywał tekst, a on zamieniał pojedyncze litery z tego tekstu na cyfry, a w kodzie:

program CodePack;


var

tekst : array [1..100] of char;


begin

writeln ('||');

read (tekst);

case tekst of

'a', 'A' : writeln ('0');

'b', 'B' : writeln ('1');

'c', 'C' : writeln ('2');

'd', 'D' : writeln ('3');

'e', 'E' : writeln ('4');

'f', 'F' : writeln ('5');

(...)

występuje błąd: Error 64: Cannot Read or Write variables of this type

proszę o pomoc :slight_smile:

teksty typu : napisz to w c++ wraz z instrukcjami mile widziane :slight_smile:


(B Brachaczek) #2

Zmienna tekst powinna być typu String. Po wczytaniu (readln, a nie read!) robisz pętlę for od 0 do length(tekst)-1 lub od 1 do length(tekst) (w normalnych językach byłoby od 0, ale nie pamiętam czy przypadkiem Pascal tu nie udziwnia... sprawdź co będzie lepiej działać). W tej pętli możesz np. pisać cyfry na ekran w zależności od case'a od tekst (zakładając, że i jest zmienną sterującą w pętli). Jeszcze lepiej od upcase(tekst__), to wtedy nie będziesz musiał sprawdzać osobno dużych i małych liter, tylko same duże.

Błąd wyskakuje Ci dlatego, że chciałbyś sprawdzać case'em zawartość całej tablicy na raz, a tak nie można - do case'a można wrzucić tylko typy całkowite (liczby i znaki).

Pozdrawiam


(Simplex111) #3

Na Twoje pytanie odpowiedział już beevvy , ale ja dodam jeszcze od siebie

Error 64 dotyczy instrukcji: read(tekst)

Oznacza, że zastosowanie procedury Read nie jest możliwe dla zmiennej typu "array of char"

Zmienną tekst zadeklarowałeś w sposób typowy dla języka C (w języku C łańcuchy deklaruje się w postaci tablicy znaków)

W Pascalu zmienną łańcuchową należy zadeklarować tak:

var tekst: string; {bez określania długości łańcucha}

lub tak:

var tekst: string[100]; {łańcuch o długości 100 znaków}

W instrukcji case nie możesz się odwołać do całego tekstu, tylko do pojedynczych znaków Instrukcja length(tekst) zwraca aktualną długość łańcucha Na koniec program, który robi to, co zakładałeś (można oczywiście udoskonalić):

program CodePack;

var tekst: string[100];

    i: integer;


begin

  write('Podaj tekst: ');

  readln(tekst);

  write('Tekst po zakodowaniu: ');

  for i:= 1 to length(tekst) do

   case tekst[i] of

     'a', 'A': write('0');

     'b', 'B': write('1');

     'c', 'C': write('2');

     'd', 'D': write('3');

     {...}

     else write('-');

   end;

  readln;

end.

Pozdrawiam


(K Ilak) #4

Dziękuję Wam serdecznie! !!


(B Brachaczek) #5

Ten kurs jest nawet sensowny: http://www.pascal.eu.org/index2.htm. Pętla for jest w 5 lekcji. (Grafikę sobie daruj).

PS Google nie boli.


(K Ilak) #6

Wiem, że Google nie boli, po prostu chciałem się od Was tego dowiedzieć :slight_smile: jeszcze raz serdecznie dziękuję :slight_smile:

-- Dodane 16.12.2009 (Śr) 18:47 --

Istnieje jeszcze jeden problem, chciałbym to zapisać do pliku .txt, a można tylko zapisywać dane ze zmiennych, nie wiecie, jak można to wszystko co zostało napisane 'spakować w zmienną' ???


(Gina Gina) #7

Chociażby, ale to jest zapis bezpośrednio do pliku, bez użycia zmiennej :stuck_out_tongue:

program CodePack;

var tekst : string[100];

    ftekst : text;

    i : integer;

begin

  Assign(ftekst, 'Codepack.txt');

  Rewrite(ftekst);


  write('Podaj tekst: ');

  readln(tekst);

  write('Tekst po zakodowaniu: ');

  for i:= 1 to length(tekst) do

   case tekst[i] of

     'a', 'A': begin write('0'); write(ftekst,'0') end;

     'b', 'B': begin write('1'); write(ftekst,'1') end;

     'c', 'C': begin write('2'); write(ftekst,'2') end;

     'd', 'D': begin write('3'); write(ftekst,'3') end;

     {...}

     else begin write('-'); write(ftekst,'-') end;

   end;


  close(ftekst);


  writeln;

  readln;

end.

a tak może być z użyciem zmiennej tekst2

program CodePack;

var tekst,

    tekst2: string[100];

    ftekst: text;

    i: integer;

begin

  tekst2:='';


  write('Podaj tekst: ');

  readln(tekst);

  write('Tekst po zakodowaniu: ');

  for i:= 1 to length(tekst) do

   case tekst[i] of

     'a', 'A': begin write('0'); tekst2:= tekst2+'0' end;

     'b', 'B': begin write('1'); tekst2:= tekst2+'1' end;

     'c', 'C': begin write('2'); tekst2:= tekst2+'2' end;

     'd', 'D': begin write('3'); tekst2:= tekst2+'3' end;

     {...}

     else begin write('-'); tekst2:= tekst2+'-' end;

  end;


  Assign(ftekst, 'Codepack.txt');

  Rewrite(ftekst);

  Write(ftekst, tekst2);

  close(ftekst);


  writeln;

  readln;

end.

(K Ilak) #8

kolejny problem: oto fragment kodu, który będzie odkodowywał dane:

VAR

t:text;

linia:string;

i: integer;

plikwyjsciowy: text;

BEGIN

clrscr;

assign(t, 'C:\tekst.txt');

reset(t);

readln(t,linia);

for i:= 1 to length(linia) do

case linia of

'0' : write ('A');

'1' : write ('B');

'2' : write ('C');

'3' : write ('D');

(...)

'1__0' : write ('K');

'14' : write ('L');

'1__5' : write ('M');

'16' : write ('N');

'1_7' : write ('O');

'18' : write ('P');

'1/9' : write ('R');

'*2*0*': write ('S');

'21*' : write ('T');

wyskakuje błąd: Constant and CASE types do not match

Jeszcze raz błagam o pomoc [-o<


(Simplex111) #9

Fragment kodu, który podałeś:

for i:= 1 to length(linia) do

case linia[i] of

'0' : write ('A');

'1' : write ('B');

'2' : write ('C');

'3' : write ('D');

(...)

'1__0' : write ('K');

'14' : write ('L');

'1__5' : write ('M');

Błąd: Constant and CASE types do not match oznacza niezgodność typu stałej wyboru z selektorem

W tym fragmencie selektorem jest wyrażenie linia , które jest pojedynczym znakiem (typ Char)

Stałe wyboru: '0', '1', '2', '3' - OK, to są znaki (typ Char)

Stałe wyboru: '1__0', '14', '1__5' - to nie są znaki, tylko łańcuchy (typ String)

Zapewne już wiesz gdzie tkwi błąd

PS. Kompilator Turbo Pascal (domyślam się że właśnie jego używasz), umiejscawia kursor bezpośrednio za instrukcją w której jest błąd, więc tam należy próbować coś zmienić gdy kompilacja się nie udała.


(K Ilak) #10

zmienna linia jest typu STRING, a zmienna i jest TYPU integer, więc nie widzę problemy :slight_smile:

co proponujecie?


(Simplex111) #11

Zmienna linia jest typu STRING - niewątpliwie TAK

Zmienna i jest typu INTEGER - to też się zgadza

Ale już linia nie jest typu STRING, tylko typu CHAR

Wyrażenie linia oznacza pojedynczy element łańcucha (zmiennej) linia

W instrukcji case sprawdzasz, czy pojedyncze elementy zmiennej linia odpowiadają danemu znakowi (ale nie łańcuchowi!)

Nie możesz sprawdzić, czy linia = '1__0'

linia:= 'to jest napis'; // poprawne wyrażenie

linia[i]:= 'to jest napis'; // błąd

linia[i]:= 'a' // poprawne wyrażenie

(K Ilak) #12

ok, ale czy możecie mi pomóc, aby jednak to zadziałało z tymi łańcuchami??? bo weście już kończę ten program, a tu taki paskudny błąd :smiley: pomóżcie :smiley:


([alex]) #13
program CodePack;Tekst:String;I:Integer;

(Simplex111) #14
program CodePack;

uses crt;


const ile = 23; {Ile znakow zawiera tablica znaki}

      maks = ile+10;

      znaki: array[11..maks] of Char = 'abcdefghijklmnoprstuwyz';

                     {Mozna dodac inne znaki do tablicy w dowolnym miejscu,

                      ale trzeba zmienic wartosc stalej 'ile' na wlasciwa.

                      Znaki spoza tablicy nie sa kodowane tylko przepisywane}

      PlikTekstowy = 'KODOWANY.TXT';


var Tekst: string[100]; {Tekst do zakodowania}

    Kodowany: string; {Tekst po zakodowaniu}

    Odkodowany: string;

    tmp: string;

    i, j, v, c: Integer;

    Litera: boolean;

    fTekst: Text;

    ch: Char;


begin

  clrscr;

  write('Podaj tekst: ');

  readln(tekst);

  writeln;

  write('Tekst po zakodowaniu: ');

  Kodowany:= '';

  for i:= 1 to length(tekst) do

    begin

      Litera:= false;

      for j:= 11 to maks do begin

        if tekst[i] = znaki[j] then begin

          Str(j, tmp);

          Kodowany:= Kodowany + tmp;

          Litera:= true;

        end;

      end;

      if not Litera then Kodowany:= Kodowany + '0' + tekst[i];

    end;

  writeln(Kodowany);

  writeln;

  write('Zapisac w pliku (t/n)? ');

  ch:= Readkey;

  if (ch = 't') or (ch = 'T') then begin

    Assign(fTekst, PlikTekstowy);

    Rewrite(fTekst);

    write(fTekst, Kodowany);

    Close(fTekst);

    writeln;

    writeln('Zapisano plik: ' + PlikTekstowy);

  end;

  writeln;

  write('Odczytac zakodowany plik (t/n)? ');

  ch:= Readkey;

  if (ch = 't') or (ch = 'T') then begin

    Assign(ftekst, PlikTekstowy);

    Reset(fTekst);

      while not Eof(fTekst) do begin

        read(fTekst, Kodowany);

      end;

    Close(fTekst);

    Odkodowany:= '';

    for i:= 1 to Length(Kodowany) do begin

      if Kodowany[i] = '0'

       then Odkodowany:= Odkodowany + Kodowany[i+1]

       else begin

         tmp:= Kodowany[i] + Kodowany[i+1];

         Val(Tmp, v, c);

         Odkodowany:= Odkodowany + znaki[v];

       end;

      Inc(i);

    end;

    writeln;

    write('Odczytano: ' + Odkodowany);

    readln;

  end;

end.