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):
$$\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}$$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>
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;
;
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. |
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:
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>
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;
return 0;
}
Zrzut:
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>
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;
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>
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;
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>
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;
}
return 0;
}