Programowanie i algorytmy

Tablice znaków

 

powrót

Tablice znaków służą do przechowywania ciągów znaków, czyli tekstu. Przy deklaracji musimy pamiętać, żeby podać o jedną komórkę więcej niż potrzebujemy, ponieważ ciąg znaków musi być zakończony specjalnym znakiem '\0' (kod ASCII = 0). Dzięki temu "zakończeniu", między innymi program wie kiedy zakończyć wypisywanie tekstu.

Poniżej przedstawiony jest schemat przechowywania tekstu "Ala ma kota". W tym przypadku potrzebujemy co najmniej dwunastu komórek tablicy (pamiętajmy, że numerowanie zaczynamy od zera):

{tex}\overset{\underline{'A'}}{0}\ \overset{\underline{'l'}}{1}\ \overset{\underline{'a'}}{2}\ \overset{\underline{'\ '}}{3}\ \overset{\underline{'m'}}{4}\ \overset{\underline{'a'}}{5}\ \overset{\underline{'\ '}}{6}\ \overset{\underline{'k'}}{7}\ \overset{\underline{'o'}}{8}\ \overset{\underline{'t'}}{9}\ \overset{\underline{'a'}}{10}\ \overset{\underline{'\backslash 0'}}{11}{/tex}

Wypełnianie tablicy znakami

Tablicę można wypełnić przy deklaracji (podobnie jak inne obiekty), pamiętając o tym szczególnym znaku na końca tablicy:

#include <iostream>
#include <cstdlib>
using namespace std;
 
int main()
{
  //pierwszy sposób
  char tab[5] = {'a','b','\0'}; //tworzymy tablicę 5-elementową, która może 
 
                                             //przechować do 4 znaków
 
  cout<< tab<< endl; //program wypisze ab
 
  //drugi sposób - nie podając wielkości tablicy - program sam dopasuje jej wielkość
  char tab2[] = {'a','b','\0'}; //tym razem tworzymy tablicę 3-elementową
 
  cout<< tab2<< endl; 
 
  //trzeci sposób - podajemy ciąg znaków pamiętając o podwójnym cudzysłowie
  char tab3[] = "Ala ma kota :)";
 
  cout<< tab3<< endl; 
  system("pause");
  return 0;
}
 

 

Wypełnianie tablicy poprzez przypisanie do danych komórek odbywa się tak samo jak na innych typach.

Zauważmy, że przy wyświetlaniu tablicy znaków podajemy tylko nazwę tablicy.

 

Wprowadzanie ciągów znaków

Podobnie jak przy wypisywaniu tekstu, do wprowadzania posługujemy się tylko nazwą tablicy. W tym miejscu należy zwrócić uwagę na działanie obiektu "cin". Dane zostaną wczytane do napotkania pierwszej spacji lub znaku końca linii. Oznacza to, że tym sposobem możemy wczytać tylko jeden wyraz.

#include<iostream>
#include<cstdlib>
using namespace std;
 
int main()
{
  char tablica[100];
  cout<<"Podaj imie i nazwisko: "; 
  cin>>tablica;
  cout<<"Twoje dane osobowe: "<<tablica<<endl; //dane zostaną zredukowane
            //do imienia
  system("pause");
  return 0;
}
 

 

Zrzut:

tablice znaków

 

Metoda getline().

Drugim sposobem, jaki można tu zastosować jest wykorzystanie metody getline() obiektu cin. Funkcja ta jest ukierunkowana na wczytywanie całych wierszy i odrzuceniem znaku końca linii. Konstrukcja wygląda następująco:

 

  cin.getline(tab, bufor);

 

gdzie tab to tablica znaków, a bufor to wielkość tej tablicy (tablica może przechować bufor - 1 znaków + znak końca tablicy).

Przeanalizujmy jeszcze raz nasz program:

#include<iostream>
#include<cstdlib>
using namespace std;
 
int main()
{
  char tablica[100];
  cout<<"Podaj imie i nazwisko: "; 
  cin.getline(tablica,100); //wykorzystanie metody getline()
  cout<<"Twoje dane osobowe: "<<tablica<<endl;
  system("pause");
  return 0;
}
 

 

Zrzut:

getlilne

 

Następną dostępną metodą jest funkcja o nazwie get() występująca w kilku wariantach. Metoda ta może działać podobnie jak getline, z tą różnicą, że znak nowego wiersza nie jest odrzucany (jak w przypadku getline()), tylko pozostaje w kolejce wejściowej. Oznacza to, że ponowne użycie  get() nie pobierze ciągu znaków, ponieważ zakłada, że nastąpił już koniec wiersza. Aby zaradzić temu problemowi można użyć innej postaci get, a mianowicie metody get() bez argumentów. Pobiera ona następny znak, a wiec znak końca linii zostanie usunięty i można ponownie wczytywać dane:

#include<iostream>
#include<cstdlib>
 
using namespace std;
 
int main()
{
  char tablica[100];
  cout<<"Podaj imie i nazwisko: "; 
 
  //wykorzystanie metody getline()
  cin.get(tablica,100); //pobranie wiersza danych
  cout<<"Twoje dane osobowe: "<<tablica<<endl; 
  cin.get(); //usunięcie znaku końca linii
  cout<<"Ponownie podaj imię i nazwisko: ";
  cin.get(tablica,100); //pobranie następnego wiersza danych
  cout<<"Twoje dane osobowe: "<<tablica<<endl; 
  system("pause");
  return 0;
}
 

 

Dokładnie ten sam efekt można osiągnąć wywołując na przemian metodę get z argumentami i bez argumentów:

#include<iostream>
#include<iostream>
#include<cstdlib>
 
using namespace std;
 
int main()
{
  char tablica[100];
  cout<<"Podaj imie i nazwisko: "; 
 
  //wykorzystanie metody getline()
  cin.get(tablica,100).get(); //pobranie wiersza danych
  cout<<"Twoje dane osobowe: "<<tablica<<endl; 
 
  cout<<"Ponownie podaj imię i nazwisko: ";
  cin.get(tablica,100).get(); //pobranie następnego wiersza danych
  cout<<"Twoje dane osobowe: "<<tablica<<endl; 
  system("pause");
  return 0;
}
 

 

Zadanie. Napisz program, który pobierze ze standardowego wejścia trzy zdania oraz wyświetli je w odwrotnej kolejności, zamieniając wszystkie male litery (tylko angielskie) na duże.

Rozwiązanie. Warto zauważyć, że numery ASCII małych liter mieszczą się w przedziale [97; 122]. Różnica między małymi i dużymi literami wynosi 32. Będziemy sprawdzać każdy znak, czy jest to mała litera. Gdy będzie spełniony warunek przesuniemy ją o 32 numery w dół aby przeskoczyć na dużą literę. Do przechowania zdań użyjemy tablicy dwuwymiarowej.

#include<iostream>
#include<cstdlib>
using namespace std;
 
int main()
{
  char zdanie[3][100];
  cout<<"Podaj pierwsze zdanie: ";
  cin.getline(zdanie[0],100);
  cout<<"Podaj drugie zdanie: ";
  cin.getline(zdanie[1],100);
  cout<<"Podaj trzecie zdanie: ";
  cin.getline(zdanie[2],100);
 
  for(int i=2;i>=0;i--) //pętla odpowiedzialna 
  {            //za wypisanie w odwrotnej kolejności
    int k = 0; //ustawienie na czytanie pierwszegj komórki tablicy
    while(zdanie[i][k]) //dopóki nie napotkamy znak końca linii, 
    {            //pętla będzie sie wykonywać
      if(zdanie[i][k]>=97&&zdanie[i][k]<=122) //sprawdzenie czy 
                                                          //znak jest małą literą
        cout<<char(zdanie[i][k]-32);   //jeśli tak to przesuwamy 
                                                         //ją do dużej litery
      else  
        cout<<(char)zdanie[i][k];
      ++k;    //przeskoczenie do następnej komórki tablicy
    }
    cout<<endl;
  }
  system("pause");
  return 0;
}