|
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:
Przeanalizujmy działanie tego programu.
Wszystko jest wspaniale, dopóki wprowadzone imię nie zawiera polskich znaków:
Co się stało? Otóż okazuje się, iż funkcja setlocale( ) zmieniła jedynie sposób wyświetlania polskich znaków. Odczyt dalej jest w LATIN 2! To zalety wspaniałego systemu Windows. W Linxie wszystko jest w porządku, a funkcja setlocale( ) wcale nie jest potrzebna. Rozwiązaniem problemu jest stworzenie prostej funkcji, która przetworzy odczytany tekst na kodowanie Win 1250:
Jak działa nasza funkcja:
Zachowaj sobie tę funkcję. Jeszcze będzie przydatna.
Strumień cin pozwala odczytywać pojedyncze wyrazy, ponieważ spacja jest separatorem. Zatem jeśli wprowadzimy imię dwuwyrazowe, np. Don Kijote, to ze strumienia zostanie pobrany tylko pierwszy wyraz:
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 getline( ). Funkcja ma dwa parametry: tablicę znakową do której zostanie wprowadzony tekst oraz maksymalną liczbę znaków w tablicy. Jeśli wprowadzony tekst jest dłuższy, to zostanie obcięty tak, aby zmieścił się w tablicy. Pozostałe znaki są usuwane ze strumienia. Ponieważ na końcu tekstu jest automatycznie dopisywany znak NUL, to do tablicy trafi tekst o liczbie znaków o jeden mniejszej od maksymalnej. Chodzi o to, aby obszar tablicy w pamięci nie został przekroczony, gdyż to mogłoby spowodować błędne działanie programu. Składnia funkcji jest następująca:
Sprawdź poniższy program:
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:
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:
| Miś Uszatek |
Dostęp do poszczególnych znaków tekstu uzyskujemy standardowo poprzez indeksy. Pierwszy znak tekstu ma indeks 0. Uruchom zmodyfikowany program:
| 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 a[0] = "L"; nie ma sensu, ponieważ komórka a[0] może przechować tylko kod znaku, a nie adres tekstu w pamięci. W trakcie przypisania w definicji tablicy:
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:
lub w postaci liczbowej :
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:
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ą #include <cstring>. Poznamy teraz kilka z tych funkcji. Wszystkich funkcji jest dużo więcej, możesz je bez problemu znaleźć w Internecie szukając wg haseł c++ cstring.
Nazwa funkcji pochodzi od słów angielskich string length = długość tekstu. Funkcja jako parametr przyjmuje adres tekstu zakończonego znakiem NUL. Jako wynik funkcja zwraca liczbę znaków od początku tekstu do znaku poprzedzającego znak NUL. Składnia funkcji jest następująca:
int strlen(tekst);
Uruchom poniższy program:
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 strlen( ).
Kolejny program wykorzystuje tablicę znakową:
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 strlen( ) możemy przekazać nazwę tablicy znakowej.
Trzeci program odczytuje dowolny tekst z okna konsoli. Polskie znaki są zamieniane z LATIN2 na kodowanie WIN1 1250, aby były poprawnie wyświetlone w oknie konsoli. Wykorzystujemy tu funkcję PL( ), którą utworzyliśmy w poprzednim podrozdziale.
Nazwa funkcji pochodzi od słów angielskich string copy = kopiowanie tekstu. Składnia funkcji jest następująca:
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:
Baba Jaga Nietoperz Gacuś Kotek Młotek |
Nazwa funkcji pochodzi od angielskich słów string catenation = połączenie tekstów. Funkcja wymaga dwóch argumentów, które są wskaźnikami:
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:
Zwróć uwagę, iż w programie do strumienia cout przekazywane są wyniki funkcji strcpy( ) i strcat( ). W obu przypadkach jest to po prostu tablica znakowa a.
Aby skorzystać w swoim programie z klasy string należy najpierw dołączyć plik nagłówkowy o nazwie string za pomocą dyrektywy #include <string>. Od tego momentu możemy korzystać z klasy string oraz z funkcji składowych tej klasy. Najpierw zobaczmy prosty przykład:
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:
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:
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:
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:
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.
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:
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:
Odczyt wiersza do zmiennej klasy string:
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 getline( ) dla klasy string wymaga dwóch lub trzech argumentów:
| 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.
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:
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 length( ) przydaje się, gdy chcemy poznać długość tekstu przechowywanego w zmiennej typu string. Zmienne klasy string nie mają ograniczeń na długość tekstu.
Uruchom program:
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:
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:
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:
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.
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:
Umożliwia dostęp do znaku w zmiennej string na pozycji, którą podamy jako parametr. Funkcja ta dokładnie odpowiada indeksowaniu w klamerkach:
Dostęp do znaku oznacza, iż program może go odczytać, np:
lub dowolnie zmodyfikować, np:
Uruchom program:
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.back() jest odpowiednikiem:
Funkcji tej nie należy używać z tekstami pustymi.
Jaś Jan |
Funkcja daje dostęp do pierwszego znaku tekstu w zmiennej string. Jest ona odpowiednikiem:
Funkcji tej nie należy używać z tekstami pustymi.
| 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.
Usuwa z tekstu w zmiennej string ostatni znak. W efekcie długość tekstu zmniejsza się o 1.
Resztę funkcji składowych poznamy w miarę potrzeb.
![]() |
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.