|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
Tekst jest ciągiem znaków ASCII, zatem do jego przechowania potrzebna jest tablica znakowa, której poszczególne komórki przechowują kolejne znaki tekstu. Tablicę znakową tworzymy wg tych samych zasad, co tablice numeryczne:
char nazwa_tablicy[liczba_znaków]; lub unsigned char nazwa_tablicy[liczba_znaków]; signed char nazwa_tablicy[liczba_znaków];
Tutaj pojawia się pewien problem. Teksty mogą mieć różną długość, czyli liczbę znaków. Aby efektywnie przetwarzać teksty, komputer musi wiedzieć, ile znaków dany tekst zawiera. W języku C++ przyjęto zasadę, iż tekst kończy się znakiem NUL, czyli kodem 0. Sam kod 0 nie należy do tekstu. Poniższy program odczytuje tekst, umieszcza go w tablicy znakowej, po czym wyświetla w oknie konsoli:
// Tekst
//------
#include <iostream>
using namespace std;
int main()
{
char imie[100];
setlocale(LC_ALL,"");
cout << "Jak brzmi twoje imię? : ";
cin >> imie;
cout << endl << "Witaj " << imie << "!"
<< endl << endl;
return 0;
}
|
Jak brzmi twoje imię? : Janusz Witaj Janusz! |
Przeanalizujmy działanie tego programu.
char imie[100]; |
Tworzymy tablicę znakową o pojemności 100 znaków. Tutaj chodzi o zapas, aby nie okazało się, iż wprowadzane imię nie zmieści się w tablicy. |
|
setlocale(LC_ALL,""); |
Ustawiamy w konsoli wyświetlanie polskich znaków Windows 1250. |
|
cin >> imie; |
Odczytujemy imię użytkownika do tablicy znakowej. Strumień wejścia automatycznie dodaje znak NUL za ostatnim znakiem tekstu. Zwróć uwagę, iż nazwa tablicy jest jednocześnie wskaźnikiem pierwszego jej znaku. |
|
cout << endl << "Witaj "
<< imie << "!"
<< endl << endl;
|
Wyświetlamy odczytane znaki. Zwróć uwagę, iż tutaj również nazwa tablicy jest potraktowana jako wskaźnik jej pierwszego znaku. |
Wszystko jest wspaniale, dopóki wprowadzone imię nie zawiera polskich znaków:
Jak brzmi twoje imię? : Świętosława Witaj -wictos?awa! |
Co się stało? Otóż okazuje się, iż funkcja
// Tekst
//------
#include <iostream>
using namespace std;
void PL(char * t)
{
while(*t)
{
switch((unsigned char)*t)
{
case 164 : *t = 165; break;
case 143 : *t = 198; break;
case 168 : *t = 202; break;
case 157 : *t = 163; break;
case 227 : *t = 209; break;
case 224 : *t = 211; break;
case 151 : *t = 140; break;
case 141 : *t = 143; break;
case 189 : *t = 175; break;
case 165 : *t = 185; break;
case 134 : *t = 230; break;
case 169 : *t = 234; break;
case 136 : *t = 179; break;
case 228 : *t = 241; break;
case 162 : *t = 243; break;
case 152 : *t = 156; break;
case 171 : *t = 159; break;
case 190 : *t = 191; break;
default : break;
}
t++;
}
}
//---------------------------------------
int main()
{
char imie[100];
setlocale(LC_ALL,"");
cout << "Jak brzmi twoje imię? : ";
cin >> imie; PL(imie);
cout << endl << "Witaj " << imie << "!"
<< endl << endl;
return 0;
}
|
Jak brzmi twoje imię? : książę_zażółć_gęślą_jaźń Witaj książę_zażółć_gęślą_jaźń! |
Jak działa nasza funkcja:
void PL(char * t) |
Funkcja w parametrze t otrzymuje adres tablicy znakowej, której znaki są w kodzie LATIN2. |
|
while(*t) |
Tworzymy pętlę, w której wskaźnik t przechodzi przez kolejne znaki tekstu, aż do napotkania kodu NUL. Wtedy wyrażenie *t ma wartość 0, czyli logicznie jest fałszywe i pętla while zakończy działanie. |
|
switch((unsigned char)*t) |
W pętli sprawdzamy kody napotkanych znaków traktowane jako liczby bez znaku (inaczej kody byłyby ujemne). |
|
kod_LATIN2: *t = kod_WIN_1250;
break;
|
Jeśli napotkany znak ma kod LATIN2 polskiego znaku, to zmieniamy go w tablicy na kod znaku. Rozkaz break; kończy działanie instrukcji zmieniane (klauzula default:). Znaki są traktowane w języku C++ jak liczby o wartości kodów tych znaków. |
|
t++; |
Po wyjściu z instrukcji zwiększany i wskazuje kolejny znak w tablicy. Wykonywane jest to na końcu każdego obiegu pętli while. |
Zachowaj sobie tę funkcję. Jeszcze będzie przydatna.
Strumień cin pozwala odczytywać pojedyncze wyrazy, ponieważ spacja
jest separatorem. Zatem jeśli wprowadzimy imię dwuwyrazowe,
Jak brzmi twoje imię? : Don Kijote Witaj Don! |
Drugi wyraz pozostanie w strumieniu i wymaga ponownego użycia cin,
aby go odczytać. Jeśli zatem chcemy odczytać cały wiersz, to musimy użyć
funkcji składowej strumienia cin o nazwie
cin.getline(tablica_znakowa,maksymalna_liczba_znaków)
Sprawdź poniższy program:
// Tekst
//------
#include <iostream>
using namespace std;
void PL(char * t)
{
while(*t)
{
switch((unsigned char)*t)
{
case 164 : *t = 165; break;
case 143 : *t = 198; break;
case 168 : *t = 202; break;
case 157 : *t = 163; break;
case 227 : *t = 209; break;
case 224 : *t = 211; break;
case 151 : *t = 140; break;
case 141 : *t = 143; break;
case 189 : *t = 175; break;
case 165 : *t = 185; break;
case 134 : *t = 230; break;
case 169 : *t = 234; break;
case 136 : *t = 179; break;
case 228 : *t = 241; break;
case 162 : *t = 243; break;
case 152 : *t = 156; break;
case 171 : *t = 159; break;
case 190 : *t = 191; break;
default : break;
}
t++;
}
}
int main()
{
char imie[100];
setlocale(LC_ALL,"");
cout << "Jak brzmi twoje imię? : ";
cin.getline(imie,100);
PL(imie);
cout << endl << "Witaj " << imie << "!"
<< endl << endl;
return 0;
}
|
Jak brzmi twoje imię? : Król Maciuś Pierwszy Długouchy lecz Wąsaty Witaj Król Maciuś Pierwszy Długouchy lecz Wąsaty! |
Tablice znakowe pozwalają przechowywać tekst, lecz nie są wygodnym rozwiązaniem. Dlatego język C++ posiada specjalne obiekty do obsługi tekstów, zwane łańcuchami tekstowymi (ang. text strings). Zacznijmy jednak od początku. Zawartość tablicy znakowej można określić w jej definicji:
char tablica_znakowa[ ] = "...dowolny tekst...";
Zwróć uwagę, iż w tym przypadku nie musimy podawać rozmiaru tablicy, kompilator wyliczy rozmiar z długości tekstu, chociaż możesz to zrobić np. w sytuacji, gdy chcesz mieć tablicę o większej liczbie znaków, niż wynika to z wprowadzanego do niej tekstu. Uruchom poniższy program:
// Tekst
//------
#include <iostream>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
char a[] = "Miś Uszatek";
cout << a << endl << endl;
return 0;
}
|
| Miś Uszatek |
Dostęp do poszczególnych znaków tekstu uzyskujemy standardowo poprzez indeksy. Pierwszy znak tekstu ma indeks 0. Uruchom zmodyfikowany program:
// Tekst
//------
#include <iostream>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
char a[] = "Miś Uszatek";
cout << a << endl;
a[0] = 'L';
a[2] = 's';
cout << a << endl << endl;
return 0;
}
|
| Miś Uszatek Lis Uszatek |
Zwróć uwagę, iż do komórek tablicy zapisujemy kody znaków. Do tego celu w
języku C++ używane są apostrofy. 'L' oznacza kod litery L, czyli
76. Zapis "L"
oznacza tekst, czyli literkę L oraz znak NUL, który jest wstawiany na końcu
tekstu i w rzeczywistości jest adresem do miejsca w pamięci, w którym kompilator
umieścił te litery. Dlatego przypisanie
char a[] = "Miś Uszatek";
komputer wykorzystuje adres tekstu "Miś Uszatek" do skopiowania poszczególnych znaków to komórek tablicy a, gdy ją tworzy. Mógłbyś wpisywać poszczególne kody znaków do tablicy:
char a[] = {'M','i','ś',' ','U','s','z','a','t','e','k','\0'};
lub w postaci liczbowej :
char a[] = {77,105,(signed char)156,32,85,115,122,97,116,101,107,0};
Przyznasz zatem, że pierwszy sposób jest najprostszy. Na końcu zawsze należy umieścić znak NUL, inaczej tekst ucieknie poza tablicę.
Gdy tablica zostanie zdefiniowana, przypisanie tekstu już nie działa:
// Tekst
//------
#include <iostream>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
char a[100];
a = "Miś Uszatek";
cout << a << endl << endl;
return 0;
}
|
Zatem, aby wprowadzić tekst do tablicy należy wykorzystać funkcję
(najlepiej biblioteczną) lub wprowadzać tekst litera po
literze do poszczególnych komórek. Funkcje operujące na tablicach znakowych
zdefiniowane są w pliku nagłówkowym cstring, który należy dołączyć do
programu dyrektywą
Nazwa funkcji pochodzi od słów angielskich
int strlen(tekst);
Uruchom poniższy program:
// Funkcje tekstowe
//-----------------
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
cout << "Liczba znaków: "
<< strlen("Miś Uszatek")
<< endl << endl;
return 0;
|
Liczba znaków: 11 |
Tekst w apostrofach jest w C++ adresem w pamięci pierwszego znaku tekstu. Dlatego
możemy go przekazać w parametrze do funkcji
Kolejny program wykorzystuje tablicę znakową:
// Funkcje tekstowe
//-----------------
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
char a[] = "Miś uszatek i lisek Chytrusek";
cout << "Liczba znaków w \"" << a << "\" = "
<< strlen(a)
<< endl << endl;
return 0;
}
|
Liczba znaków w "Miś uszatek i lisek Chytrusek" = 29 |
Tutaj tworzymy tablicę znakową a i wprowadzamy do niej tekst.
Następnie wypisujemy tekst oraz jego długość. Jeśli chcemy wyświetlić cudzysłów,
to poprzedzamy go znakiem \. Inaczej cudzysłów zostanie potraktowany jako znak
końca tekstu, czyli tzw. delimiter. Nazwa tablicy jest adresem jej
pierwszego znaku. Zatem jako parametr
Trzeci program odczytuje dowolny tekst z
okna konsoli. Polskie znaki są zamieniane z LATIN2 na kodowanie
// Funkcje tekstowe
//-----------------
#include <iostream>
#include <cstring>
using namespace std;
void PL(char * t)
{
while(*t)
{
switch((unsigned char)*t)
{
case 164 : *t = 165; break;
case 143 : *t = 198; break;
case 168 : *t = 202; break;
case 157 : *t = 163; break;
case 227 : *t = 209; break;
case 224 : *t = 211; break;
case 151 : *t = 140; break;
case 141 : *t = 143; break;
case 189 : *t = 175; break;
case 165 : *t = 185; break;
case 134 : *t = 230; break;
case 169 : *t = 234; break;
case 136 : *t = 179; break;
case 228 : *t = 241; break;
case 162 : *t = 243; break;
case 152 : *t = 156; break;
case 171 : *t = 159; break;
case 190 : *t = 191; break;
default : break;
}
t++;
}
}
int main()
{
setlocale(LC_ALL,"");
char a[256];
cout << "Wpisz swój tekst: ";
cin.getline(a,256);
PL(a);
cout << "Liczba znaków tekstu \"" << a << "\" = "
<< strlen(a)
<< endl << endl;
return 0;
}
|
Wpisz swój tekst: Aligator Józek zjadł swój wózek Liczba znaków tekstu "Aligator Józek zjadł swój wózek" = 31 |
Nazwa funkcji pochodzi od słów angielskich
char * strcpy(tekst_docelowy,tekst_źródłowy)
Jako argumenty funkcja wymaga dwóch adresów (wskaźników): tekst_docelowy jest adresem tablicy znakowej, do której trafi tekst spod adresu tekst_źródłowy. Tekst źródłowy jest kopiowany znak po znaku do momentu, aż funkcja skopiuje znak NUL. Wtedy kopiowanie się kończy. Należy zadbać, aby tablica docelowa miała wystarczającą pojemność na tekst źródłowy. Dzięki tej funkcji możemy wprowadzać do tablicy znakowej tekst, czyli jest ona ograniczonym odpowiednikiem operacji przypisania. Wynikiem funkcji jest adres tekstu docelowego. Tekst docelowy i tekst źródłowy nie powinny się pokrywać w pamięci. Uruchom poniższy program:
int main()
{
setlocale(LC_ALL,"");
char a[256];
strcpy(a,"Baba Jaga");
cout << a << endl;
strcpy(a,"Nietoperz Gacuś");
cout << a << endl;
strcpy(a,"Kotek Młotek");
cout << a << endl << endl;
return 0;
}
|
Baba Jaga Nietoperz Gacuś Kotek Młotek |
Nazwa funkcji pochodzi od angielskich słów s
char * strcat(tekst_docelowy,tekst_źródłowy);
Tekst źródłowy zostaje dołączony na końcu tekstu docelowego w ten sposób, iż kończący znak NUL tekstu docelowego jest nadpisywany pierwszym znakiem tekstu źródłowego. Kolejne znaki tekstu źródłowego są następnie kopiowane do tekstu docelowego aż do skopiowania znaku NUL. Funkcja zwraca w wyniku wskaźnik do tekstu docelowego. Tablica docelowa powinna posiadać wystarczającą pojemność, aby przechować oba teksty. Uruchom program:
// Funkcje tekstowe
//-----------------
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
char a[256];
cout << strcpy(a,"Miś Uszatek") << endl;
cout << strcat(a," i klapnięte uszko ma")
<< endl << endl;
return 0;
}
|
Miś Uszatek Miś Uszatek i klapnięte uszko ma |
Zwróć uwagę, iż w programie do strumienia cout przekazywane są wyniki
funkcji
Aby skorzystać w swoim programie z klasy string należy
najpierw dołączyć plik nagłówkowy o nazwie string za pomocą dyrektywy
// Klasa string
//-------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a;
a = "Miś Uszatek";
a += " lubi miodek!";
a += "\n" + a;
cout << a << endl << endl;
return 0;
}
|
Miś Uszatek lubi miodek! Miś Uszatek lubi miodek! |
Jak widzisz, zmienna a klasy string zachowuje się jak normalna zmienna. Działa dla niej operator przypisania oraz niektóre operatory modyfikacji. Przeanalizujmy ważniejsze elementy w programie:
#include <string> |
dołączamy plik nagłówkowy z definicją klasy string. Od tego momentu otrzymujemy nowy typ string i możemy tworzyć zmienne klasy string. |
|
string a; |
Tworzymy zmienną a klasy string. Nowo utworzona zmienna zawiera tekst pusty. |
|
a = "text1"; |
Instrukcja przypisania umieszcza w zmiennej a tekst1. |
|
a += "text2"; |
Instrukcja modyfikacji. Operator dodawania + oznacza dla tekstów łączenie, zatem tekst2 zostanie dopisany na koniec tekstu, który już znajduje się w zmiennej a. W rezultacie w zmiennej a otrzymamy połączone ze sobą tekst1 i tekst2. |
|
a += "\n" + a; |
Na koniec połączonych tekstów w zmiennej a zostaje wstawiony znak końca wiersza /n oraz poprzednia zawartość zmiennej a. W wyniku tekst w a zostanie zdublowany. |
|
cout << a
<< endl
<< endl;
|
Przesłanie zmiennej a do strumienia cout spowoduje wyświetlenie w oknie konsoli jej zawartości. Będą to dwa wiersze, ponieważ pomiędzy nimi został wstawiony znak końca wiersza \n. |
Już ten prosty przykład pokazuje, iż zmienna typu string jest prostsza w obsłudze od tablicy znakowej char, dlatego w dalszej części tego kursu będziemy używali wyłącznie klasy string do tekstów.
Zmienna string może być zainicjowana określoną treścią już w momencie tworzenia:
string zmienna("...tekst...");
// Klasa string
//-------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a("Cześć, tu string :)");
cout << a << endl << endl;
return 0;
}
|
Cześć, tu string :) |
Wygląda to jak wywołanie funkcji i faktycznie nim jest. Gdy zmienna klasy jest tworzona w pamięci komputera, zostaje wywołana specjalna funkcja składowa tej klasy zwana konstruktorem. Zadaniem konstruktora jest odpowiednie przygotowanie utworzonego obiektu do pracy w programie. Standardowy konstruktor ustawia długość tekstu w zmiennej string na 0, czyli na tekst pusty, który nie zawiera żadnego znaku. Zmieniamy to podając w parametrze dla konstruktora tekst, który chcemy, aby znalazł się w zmiennej od początku jej istnienia. Wszystko to omówimy dokładnie przy klasach C++ w dalszej części kursu.
Można też użyć operatora przypisania, jak w normalnych zmiennych:
string a = "Cześć, tu string :)";
Dostęp do poszczególnych znaków w zmiennej string uzyskuje się przy pomocy indeksów tak samo jak dla tablicy.
Liczbę znaków (a właściwie liczbę bajtów, jednak dla kodu ASCII jest to to samo) zwraca funkcja składowa lenght( ). Funkcję składową klasy zawsze wywołujemy z nazwą zmiennej oddzieloną operatorem kropka:
zmienna_string.length();
Kolejny program odczytuje jeden wyraz ze strumienia cin i umieszcza go w zmiennej typu string. Następnie program wyświetla liczbę znaków w wyrazie oraz kolejne znaki wyrazu i ich kody. W programie umieściliśmy zmodyfikowaną dla klasy string funkcję PL( ), która zamienia znaki w kodzie LATIN2 na kod WIN 1250.
// Klasa string
//-------------
#include <iostream>
#include <string>
using namespace std;
void PL(string & t)
{
unsigned i,len = t.length();
for(i = 0; i < len; i++)
switch((unsigned char) t[i])
{
case 164 : t[i] = 165; break;
case 143 : t[i] = 198; break;
case 168 : t[i] = 202; break;
case 157 : t[i] = 163; break;
case 227 : t[i] = 209; break;
case 224 : t[i] = 211; break;
case 151 : t[i] = 140; break;
case 141 : t[i] = 143; break;
case 189 : t[i] = 175; break;
case 165 : t[i] = 185; break;
case 134 : t[i] = 230; break;
case 169 : t[i] = 234; break;
case 136 : t[i] = 179; break;
case 228 : t[i] = 241; break;
case 162 : t[i] = 243; break;
case 152 : t[i] = 156; break;
case 171 : t[i] = 159; break;
case 190 : t[i] = 191; break;
default : break;
}
}
int main()
{
setlocale(LC_ALL,"");
string a;
cout << "Wpisz pojedynczy wyraz: ";
cin >> a;
PL(a); // Korekcja odczytanych kodów
cout << endl << "Liczba znaków : " << a.length()
<< endl << endl;
for(unsigned i = 0; i < a.length(); i++)
cout << "Znak: " << a[i]
<< " kod: " << (int)(unsigned char)a[i]
<< endl;
cout << endl;
return 0;
}
|
Wpisz pojedynczy wyraz: książę Liczba znaków : 6 Znak: k kod: 107 Znak: s kod: 115 Znak: i kod: 105 Znak: ą kod: 185 Znak: ż kod: 191 Znak: ę kod: 234 |
Przeanalizujmy ważniejsze elementy tego programu:
string a; |
Tworzymy zmienną a klasy string. Zmienna a nie zawiera żadnego tekstu. |
|
cin >> a; |
Do zmiennej a odczytujemy jeden wyraz znaków ze strumienia cin. Jeśli wprowadzisz więcej niż jeden wyraz, ze strumienia cin zostanie odczytany ylko pierwszy z nich. Spacja jest traktowana jako koniec wyrazu. Spacje początkowe są ignorowane. |
|
cout ...
<< a.length()
...
|
Do strumienia wyjściowego cout przekazujemy liczbę znaków w zmiennej a, czyli w odczytanym wyrazie. |
|
for(
unsigned i = 0;
i < a.length();
i++
)
...
|
Pętla for wykona się tyle razy, ile wynosi liczba znaków w a. Zmienna i przebiegnie indeksy wszystkich znaków w a. Jeśli chcesz przyspieszyć działanie tej pętli, to liczbę znaków zapamiętaj w osobnej zmiennej i ją użyj w porównaniu. Dzięki temu komputer nie będzie musiał liczyć znaków w a w każdym obiegu pętli. Tak zrobiliśmy w funkcji PL( ): unsigned i, len = a.length();for(i = 0; i < len; i++)... |
|
cout ...
<< a[i] ...
|
Do strumienia cout trafia znak ze zmiennej a, który znajduje się na pozycji i-tej. |
|
cout ...
<< (int)
(unsigned char)
a[i]
...
|
Ta dziwna konstrukcja ma za zadanie przesłanie do strumienia cout kodu znaku jako liczby nieujemnej 8-bitowej. Dokonujemy tego dwoma rzutowaniami, które należy czytać od strony prawej do lewej. Najpierw znak a[i] zostaje zamieniony na znak typu unsigned char, a następnie ten znak zmieniany jest w typ int. W efekcie dla kodów rozszerzonych otrzymujemy liczbę dodatnią z zakresu od 128 do 255. Bez rzutowania kody rozszerzone ASCII byłyby ujemne, ponieważ prosty typ char jest 8-bitowym odpowiednikiem typu int i jest interpretowany jako 8-bitowa liczba U2. |
Jeśli chcemy odczytać cały wiersz ze strumienia, używamy funkcji getline( ), jednak w tym przypadku funkcja ta należy do klasy string i nie jest funkcją składową strumienia cin. Jest to inna funkcja, posiada ona jedynie taką samą nazwę:
Odczyt wiersza do tablicy char:
cin.getline(tablica_char,liczba_znaków);
Odczyt wiersza do zmiennej klasy string:
getline(cin,zmienna_string,{delimiter})
To
częsta praktyka w języku C++. Mogą istnieć różne funkcje o tej samej nazwie tak,
jak mogą istnieć różni uczniowie o tym samym nazwisku lub imieniu. Funkcja
| cin | Strumień wejścia, z którego będą odczytywane znaki tworzące wiersz. W tym miejscu może pojawić się dowolny inny strumień wejścia, niekoniecznie musi to być cin – w ten sposób możemy odczytywać wiersz z różnych urządzeń, np. z pliku na dysku czy z pamięci komputera, co zobaczymy później. |
|
| zmienna_string | Zmienna klasy string, w której zostanie umieszczony wiersz znaków. Nie ma tutaj ograniczenia na długość wiersza, gdyż zmienne string dynamicznie dopasowują się do ilości danych. |
|
| {delimiter} | Ten parametr nie jest obowiązkowy. Możesz go nie podawać w wywołaniu funkcji. Jeśli go pominiesz, to wiersz zostanie wczytany do momentu napotkania w strumieniu znaku końca wiersza \n. W przeciwnym razie odczyt będzie następował aż do napotkania znaku delimitera. W obu przypadkach znak kończący wiersz (\n lub delimiter) jest usuwany ze strumienia, lecz nie jest wstawiany do zmiennej string. |
Uruchom poniższy program. Odczytuje on wiersz znaków, po czym wypisuje go wspak.
// Klasa string
//-------------
#include <iostream>
#include <string>
using namespace std;
void PL(string & t)
{
unsigned i,len = t.length();
for(i = 0; i < len; i++)
switch((unsigned char) t[i])
{
case 164 : t[i] = 165; break;
case 143 : t[i] = 198; break;
case 168 : t[i] = 202; break;
case 157 : t[i] = 163; break;
case 227 : t[i] = 209; break;
case 224 : t[i] = 211; break;
case 151 : t[i] = 140; break;
case 141 : t[i] = 143; break;
case 189 : t[i] = 175; break;
case 165 : t[i] = 185; break;
case 134 : t[i] = 230; break;
case 169 : t[i] = 234; break;
case 136 : t[i] = 179; break;
case 228 : t[i] = 241; break;
case 162 : t[i] = 243; break;
case 152 : t[i] = 156; break;
case 171 : t[i] = 159; break;
case 190 : t[i] = 191; break;
default : break;
}
}
int main()
{
setlocale(LC_ALL,"");
string a;
cout << "Wpisz poniżej wiersz znaków:" << endl;
getline(cin,a); PL(a);
for(unsigned i = a.length(); i > 0; i--)
cout << a[i - 1];
cout << endl << endl;
return 0;
}
|
Wpisz poniżej wiersz znaków: Zażółć żabią jaźń, książę! !ężąisk ,ńźaj ąibaż ćłóżaZ |
Zaletą klasy string jest jej integracja ze środowiskiem języka C++. Język C++ jest językiem obiektowym, a jego obiekty potrafią ze sobą współpracować. Funkcja składowa (ang. member function) jest funkcją, która została skojarzona z obiektem, jest jakby jego częścią składową i posiada bezpośredni dostęp do elementów obiektu oraz do innych jego funkcji składowych. Jeśli utworzysz kilka zmiennych klasy string, to każda z nich posiada swoje własne funkcje składowe o tych samych nazwach. Dostęp do nich uzyskuje się za pomocą operatora kropki . (ang. dot operator – member selection operator), który służy do wyboru elementu składowego obiektu. Składnia jest następująca:
obiekt.element_składowy; obiekt.funkcja_składowa(argumenty);
Omówimy teraz kilka przydatnych funkcji składowych zmiennych klasy string.
Tę funkcję już poznaliśmy. Zwraca ona liczbę bajtów zawartych w zmiennej
klasy string. Dla kodu ASCII będzie to to samo, co liczba znaków
(możliwe jest również inne kodowanie, ale tym sobie nie
zawracajmy na początku głowy). Funkcja
Uruchom program:
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a = "ABC:";
do
{
cout << "Długość : " << a.length() << endl
<< "Tekst w a: " << a << endl << endl;
a += "X";
} while(a.length() <= 10);
return 0;
}
|
Długość : 4 Tekst w a: ABC: Długość : 5 Tekst w a: ABC:X Długość : 6 Tekst w a: ABC:XX Długość : 7 Tekst w a: ABC:XXX Długość : 8 Tekst w a: ABC:XXXX Długość : 9 Tekst w a: ABC:XXXXX Długość : 10 Tekst w a: ABC:XXXXXX |
Funkcja zmienia rozmiar tekstu w zmiennej string. Posiada jeden lub dwa parametry:
zmienna_string.resize(rozmiar); zmienna_string.resize(rozmiar,znak);
Pierwsza postać używana jest najczęściej do zmniejszania długości tekstu. Rozmiar określa nową długość tekstu w zmiennej. Jeśli rozmiar jest mniejszy od aktualnej długości tekstu w zmiennej, to tekst zostanie obcięty do rozmiaru. Jeśli rozmiar jest większy od długości tekstu, to tekst zostanie powiększony do rozmiaru przez dodanie na końcu znaków NUL, które są traktowane w zmiennej string jako normalne znaki i nie oznaczają końca tekstu jak w tablicach char. Uruchom program:
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a = "Kubuś i Prosiaczek";
cout << a << endl;
a.resize(5);
cout << a << "?" << endl << endl;
return 0;
}
|
Kubuś i Prosiaczek Kubuś? |
Poeksperymentuj z tym programem zwiększając rozmiar.
Druga postać posiada dodatkowo parametr znak. Jeśli tekst ma więcej znaków niż rozmiar, to zostanie obcięty do rozmiaru. Jeśli tekst ma mniej znaków niż rozmiar, to zostanie uzupełniony podanym znakiem aż do osiągnięcia rozmiaru. Uruchom poniższy program:
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a = "Programowanie w języku C";
cout << a << endl;
a.resize(a.length() + 2,'+');
cout << a << endl;
a.resize(a.length() - 13,'-');
cout << a << endl << endl;
return 0;
}
|
Programowanie w języku C Programowanie w języku C++ Programowanie |
Funkcja zwraca wartość logiczną true, jeśli tekst zawarty w zmiennej string jest pusty (tzn. nie zawiera żadnego znaku). W przeciwnym razie zwracane jest false.
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
void PL(string & t)
{
unsigned i,len = t.length();
for(i = 0; i < len; i++)
switch((unsigned char) t[i])
{
case 164 : t[i] = 165; break;
case 143 : t[i] = 198; break;
case 168 : t[i] = 202; break;
case 157 : t[i] = 163; break;
case 227 : t[i] = 209; break;
case 224 : t[i] = 211; break;
case 151 : t[i] = 140; break;
case 141 : t[i] = 143; break;
case 189 : t[i] = 175; break;
case 165 : t[i] = 185; break;
case 134 : t[i] = 230; break;
case 169 : t[i] = 234; break;
case 136 : t[i] = 179; break;
case 228 : t[i] = 241; break;
case 162 : t[i] = 243; break;
case 152 : t[i] = 156; break;
case 171 : t[i] = 159; break;
case 190 : t[i] = 191; break;
default : break;
}
}
int main()
{
setlocale(LC_ALL,"");
string a;
cout << "Wprowadź poniżej wiersz tekstu:" << endl;
getline(cin,a); PL(a); cout << endl;
while(!a.empty()) // Dopóki tekst NIE pusty
{
a.resize(a.length()-1);
cout << a << "***" << endl;
}
cout << endl;
return 0;
}
|
Wprowadź poniżej wiersz tekstu: Zażółć żabią jaźń Zażółć żabią jaź*** Zażółć żabią ja*** Zażółć żabią j*** Zażółć żabią *** Zażółć żabią*** Zażółć żabi*** Zażółć żab*** Zażółć ża*** Zażółć ż*** Zażółć *** Zażółć*** Zażół*** Zażó*** Zaż*** Za*** Z*** *** |
Czyści zmienną string, tzn. usuwa cały tekst zawarty w zmiennej. Tę samą operację można wykonać przypisując zmiennej tekst pusty:
zmienna_string = "";
Uruchom program:
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a = "Krokodyl Arek";
cout << "a = \"" << a << "\", liczba znaków = "
<< a.length() << endl;
a.clear(); // Usuwamy tekst ze zmiennej
cout << "a = \"" << a << "\", liczba znaków = "
<< a.length() << endl << endl;
return 0;
}
|
a = "Krokodyl Arek", liczba znaków = 13 a = "", liczba znaków = 0 |
Umożliwia dostęp do znaku w zmiennej string na pozycji, którą podamy jako parametr. Funkcja ta dokładnie odpowiada indeksowaniu w klamerkach:
zmienna_string.at(pozycja) <---> zmienna_string[pozycja]
Dostęp do znaku oznacza, iż program może go odczytać, np:
cout << zmienna_string.at(pozycja) ...
lub dowolnie zmodyfikować, np:
zmienna_string.at(pozycja) = 'nowy znak';
Uruchom program:
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a = "Ala ma chomika";
cout << a << endl;
for(int i = a.length()-1; i >= 0; i--)
cout << a.at(i);
cout << endl << endl;
return 0;
}
|
Ala ma chomika akimohc am alA |
Zmień w programie wywołanie a.at(i) na a[i].
Funkcja daje dostęp do ostatniego znaku tekstu przechowywanego w zmiennej
string.
zmienna_string.at(zmienna_string.length()-1) lub zmienna_string[zmienna_string.length()-1]
Funkcji tej nie należy używać z tekstami pustymi.
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a = "Jaś";
cout << a << endl;
a.back() = 'n';
cout << a << endl;
return 0;
}
|
Jaś Jan |
Funkcja daje dostęp do pierwszego znaku tekstu w zmiennej string. Jest ona odpowiednikiem:
zmienna_string.at(0)lubzmienna_string[0]
Funkcji tej nie należy używać z tekstami pustymi.
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
string a = "jeść";
cout << a << endl;
a.front() = 't';
cout << a << endl;
return 0;
}
|
| jeść teść |
Funkcja jako parametr przyjmuje znak, który zostanie dołączony na końcu bieżącego tekstu w zmiennej string. W efekcie długość tekstu wzrasta o 1.
zmienna_string.push_back(znak)
Usuwa z tekstu w zmiennej string ostatni znak. W efekcie długość tekstu zmniejsza się o 1.
zmienna_string.pop_back()
// Funkcje składowe string
//------------------------
#include <iostream>
#include <string>
using namespace std;
int main()
{
string a;
for(char i = 'a'; i <= 'z'; i++)
a.push_back(i);
do
{
cout << a << endl;
a.pop_back();
} while(!a.empty());
return 0;
}
|
abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxy abcdefghijklmnopqrstuvwx abcdefghijklmnopqrstuvw abcdefghijklmnopqrstuv abcdefghijklmnopqrstu abcdefghijklmnopqrst abcdefghijklmnopqrs abcdefghijklmnopqr abcdefghijklmnopq abcdefghijklmnop abcdefghijklmno abcdefghijklmn abcdefghijklm abcdefghijkl abcdefghijk abcdefghij abcdefghi abcdefgh abcdefg abcdef abcde abcd abc ab a |
Resztę funkcji składowych poznamy w miarę potrzeb.
zmienna_string.length().zmienna_string.resize(rozmiar) i
zmienna_string.resize(rozmiar,znak).zmienna_string.empty().zmienna_string.clear(). Jak można inaczej
zrealizować tę operację?zmienna_string.at(pozycja). Jak można
inaczej zrealizować tę operację?zmienna_string.back(). Jak można inaczej
zrealizować tę operację?zmienna_string.front(). Jak można inaczej
zrealizować tę operację?zmienna_string.push_back(znak). Jak można
inaczej zrealizować tę operację?zmienna_string.pop_back(). Jak można
inaczej zrealizować tę operację?
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.