Przejdź do głównej zawartości

Napisy

W tej lekcji dowiesz się, jak używać zmiennych przechowujących tekst. Jako ludzie, tekst jest podstawowym medium, poprzez które wchodzimy w interakcję z programami komputerowymi. Poznanie podstawowych zasad przechowywania tekstu i manipulacji nim jest kluczowe dla tworzenia funkcjonalnych aplikacji, z których ludzie mogą i chcą korzystać.

Motywacja

Zmienne typu tekstowego są bardzo przydatne. Przykładem niech będzie program, który wczytuje imie użytkownika, po czym wita go podając ilość znaków w jego imieniu.

Program wczytujący imie
#include <iostream>
#include <string>

int main()
{
std::string name;
std::cout << "Podaj swoje imie: ";
std::cin >> name;
std::cout << "Witaj, " << name << "!\n";
std::cout << "Twoje imie ma " << name.size() << " znakow.\n";
}

Typ przechowujący tekst

W poprzednich lekcjach mówiliśmy o różnych typach zmiennych, głównie tych, które przechowują liczby. Wspomnieliśmy też o typie char (od ang.: character), który przechowuje pojedynczy znak.

W programowaniu, na tekst mówi się łańcuch znaków (ang.: string). W C++ istnieje typ, który pozwala nam przechowywać i manipulować takimi łańcuchami i jest to std::string.

Plik nagłówkowy

Aby móc poprawnie korzystać z std::string musimy dodać do kodu nagłówek string, w ten sam sposób co wcześniej iostream:

#include <string>

Typu std::string używamy tak jak każdego innego. Tutaj deklarujemy dwie zmienne - jedną o typie int oraz jedną o typie std::string.

Używanie typu string
int number;
std::string text;

Inicjalizacja

Przypisanie początkowej wartości wygląda tak samo jak w przypadku zmiennych o innych typach, przy czym należy pamiętać, że tekst podajemy między cudzysłowami, nie pojedynczymi apostrofami:

Inicjalizacja i wypisanie zmiennej typu string
std::string welcome = "Hello, World!";
std::cout << welcome;

Jeśli nie podamy żadnej wartości, nasz łańcuch znaków będzie pusty. Jego długość będzie wynosić 0, a po wypisaniu na konsolę nie zobaczymy nic,

Operacje na napisach

Interakcja z użytkownikiem

Napisy możemy wyświetlać za pomocą std::cout oraz wczytywać za pomocą std::cin.

Wczytanie imienia i powitanie
#include <iostream>
#include <string>

int main()
{
std::string name;
std::cout << "Podaj swoje imie: ";
std::cin >> name;
std::cout << "Witaj, " << name << "!\n";
}

Zauważ, że std::cin pobiera tekst do napotkania pierwszego białego znaku, czyli np. spacji, znaku nowej linii czy tabulatora. Przez to, jeśli podamy swoje imię i nazwisko to do zmiennej name trafi jedynie imię. Aby pobrać całą linię możemy użyć std::getline:

Wczytywanie całej linii tekstu
std::string full_name;
std::getline(std::cin, full_name);

std::getline jest funkcją, która przyjmuje dwa argumenty - strumień wejściowy do odczytania linii oraz zmienną std::string do której ta linia zostanie zapisana. Ten przykład pokazuje jak można użyć tej funkcji do odczytania linii z std::cin. Tak więc funkcję tę "wywołujemy" umieszczając nazwę funkcji std::getline, następnie nawiasy (...), a wewnątrz nawiasów argumenty, które chcemy podać, oddzielone przecinkiem: std::cin, full_name.

Łączenie

Operatory + i += mogą być użyte do konkatenacji dwóch napisów oraz dołączenia jednego napisu do drugiego. Rozważmy następujący skrócony przykład z wejściem Dwayne Johnson:

Konkatenacja i dołączanie
std::string first_name;
std::string last_name;

std::cin >> first_name;
std::cin >> last_name;

// Konkatenacja
std::string cool_name = first_name + " \"The Rock\" " + last_name;
std::cout << "Your cool name is:\n" << cool_name << "\n\n";

// Dołączanie
cool_name += " Mk II";
std::cout << "Your new name is:\n" << cool_name;
Result
Your cool name is:
Dwayne "The Rock" Johnson

Your new name is:
Dwayne "The Rock" Johnson Mk II

Zauważ, że cool_name jest wynikiem konkatenacji trzech łańcuchów - first_name, "The Rock" i last_name. Dalej w kodzie można zobaczyć, jak modyfikujemy cool_name poprzez dołącznie do niego " Mk II".

Sprawdzanie długości

Aby sprawdzić ile znaków znajduje się w łancuchu używamy tak zwanej metody size. O funkcjach i metodach będziemy mówić więcej w dalszej części kursu, gdyż są one bardzo ważnym pojęciem.

Zobaczmy jak wykorzystać metodę size w praktyce. Rozważmy następujący przykład z wejściem Johnny:

Program liczący długość imienia
#include <iostream>
#include <string>

int main()
{
std::string name;
std::cout << "Enter your name: ";
std::cin >> name;

std::cout << "\nWelcome, " << name << "!\n";
std::cout << "Your name has " << name.size() << " characters.\n";
}
Result
Welcome, Johnny!
Your name has 6 characters.

Metodę size wywołujemy na zmiennej name w następujący sposób: name.size(). Symbol . wskazuje, że mamy dostęp do czegoś na naszej zmiennej name. size jest nazwą metody, do której uzyskujemy dostęp.

Użycie nawiasów () * wywołuje* metodę size. Ta zwraca nam całkowitą liczbę znaków w napisie.

Te pojęcia nie są teraz kluczowe do zapamiętania, ale zobaczysz je później w lekcjach Funkcje i Metody; po prostu zapamiętaj jak ich używać.

Dla przypomnienia, określamy zmienną (name), następnie piszemy size po kropce, a potem puste nawiasy okrągłe:

Wywołanie metody size
name.size()

Konwersja pomięzdy liczbami i tekstem

Liczby i łańcuchy nie mogą być swobodnie konwertowane na siebie bez specjalnych funkcji, która robią to za nas. Dzieje się tak dlatego, że typy liczbowe i typy łańcuchów w C++ są zdecydowanie różne i nie są ogólnie kompatybilne. Choć może to być denerwujące, jest to w rzeczywistości bardzo ważne dla tworzenia kodu wolnego od błędów.

53
"53"

Pierwszą wartością jest liczba 53. Reprezentuje ona wartość, na której możemy wykonywać operacje matematyczne. Druga wartość to tekst składający się ze znaków '5' i '3'. Nie możemy wykonywać operacji matematycznych na łańcuchach; raczej, operacje na łańcuchach, które możemy wykonać to konkatenacje.

Następujące kawałki kodu to nieudolne i niepoprawne (kończące się błędem kompilacji) próby konwersji między łańcuchami a liczbami:

❌ Przypisywanie zmiennej liczbowej do łańcucha
int number = 53;
std::string number_in_str = number; // Błąd

Aby przekonwertować z typu liczbowego (np. int czy float) na typ łańcuchowy, musimy użyć funkcji std::to_string.

✔ Konwersja liczby na napis
int number = 53;
std::string number_in_str = std::to_string(number);

W ten sam sposób, jeśli mamy wewnątrz łańcucha znaków zapisaną liczbę, możemy ją przekonwertować na inta za pomocą std::stoi (od ang.: string to int) oraz typu float za pomocą std::stof (od ang.: string to float):

Konwersja std::string na int
std::string number_in_str = "53";
int number = std::stoi(number_in_str);

Podsumowanie

W tej lekcji dowiedzieliśmy się o typie std::string, który służy do przechowywania i manipulowania sekwencjami znaków.

dobra rada

Zobacz następujące podlekcje, aby zapoznać się lepiej z łańcuchami znaków:

Napisy

W tej lekcji dowiesz się, jak używać zmiennych przechowujących tekst. Jako ludzie, tekst jest podstawowym medium, poprzez które wchodzimy w interakcję z programami komputerowymi. Poznanie podstawowych zasad przechowywania tekstu i manipulacji nim jest kluczowe dla tworzenia funkcjonalnych aplikacji, z których ludzie mogą i chcą korzystać.

Motywacja

Zmienne typu tekstowego są bardzo przydatne. Przykładem niech będzie program, który wczytuje imie użytkownika, po czym wita go podając ilość znaków w jego imieniu.

Program wczytujący imie
#include <iostream>
#include <string>

int main()
{
std::string name;
std::cout << "Podaj swoje imie: ";
std::cin >> name;
std::cout << "Witaj, " << name << "!\n";
std::cout << "Twoje imie ma " << name.size() << " znakow.\n";
}

Typ przechowujący tekst

W poprzednich lekcjach mówiliśmy o różnych typach zmiennych, głównie tych, które przechowują liczby. Wspomnieliśmy też o typie char (od ang.: character), który przechowuje pojedynczy znak.

W programowaniu, na tekst mówi się łańcuch znaków (ang.: string). W C++ istnieje typ, który pozwala nam przechowywać i manipulować takimi łańcuchami i jest to std::string.

Plik nagłówkowy

Aby móc poprawnie korzystać z std::string musimy dodać do kodu nagłówek string, w ten sam sposób co wcześniej iostream:

#include <string>

Typu std::string używamy tak jak każdego innego. Tutaj deklarujemy dwie zmienne - jedną o typie int oraz jedną o typie std::string.

Używanie typu string
int number;
std::string text;

Inicjalizacja

Przypisanie początkowej wartości wygląda tak samo jak w przypadku zmiennych o innych typach, przy czym należy pamiętać, że tekst podajemy między cudzysłowami, nie pojedynczymi apostrofami:

Inicjalizacja i wypisanie zmiennej typu string
std::string welcome = "Hello, World!";
std::cout << welcome;

Jeśli nie podamy żadnej wartości, nasz łańcuch znaków będzie pusty. Jego długość będzie wynosić 0, a po wypisaniu na konsolę nie zobaczymy nic,

Operacje na napisach

Interakcja z użytkownikiem

Napisy możemy wyświetlać za pomocą std::cout oraz wczytywać za pomocą std::cin.

Wczytanie imienia i powitanie
#include <iostream>
#include <string>

int main()
{
std::string name;
std::cout << "Podaj swoje imie: ";
std::cin >> name;
std::cout << "Witaj, " << name << "!\n";
}

Zauważ, że std::cin pobiera tekst do napotkania pierwszego białego znaku, czyli np. spacji, znaku nowej linii czy tabulatora. Przez to, jeśli podamy swoje imię i nazwisko to do zmiennej name trafi jedynie imię. Aby pobrać całą linię możemy użyć std::getline:

Wczytywanie całej linii tekstu
std::string full_name;
std::getline(std::cin, full_name);

std::getline jest funkcją, która przyjmuje dwa argumenty - strumień wejściowy do odczytania linii oraz zmienną std::string do której ta linia zostanie zapisana. Ten przykład pokazuje jak można użyć tej funkcji do odczytania linii z std::cin. Tak więc funkcję tę "wywołujemy" umieszczając nazwę funkcji std::getline, następnie nawiasy (...), a wewnątrz nawiasów argumenty, które chcemy podać, oddzielone przecinkiem: std::cin, full_name.

Łączenie

Operatory + i += mogą być użyte do konkatenacji dwóch napisów oraz dołączenia jednego napisu do drugiego. Rozważmy następujący skrócony przykład z wejściem Dwayne Johnson:

Konkatenacja i dołączanie
std::string first_name;
std::string last_name;

std::cin >> first_name;
std::cin >> last_name;

// Konkatenacja
std::string cool_name = first_name + " \"The Rock\" " + last_name;
std::cout << "Your cool name is:\n" << cool_name << "\n\n";

// Dołączanie
cool_name += " Mk II";
std::cout << "Your new name is:\n" << cool_name;
Result
Your cool name is:
Dwayne "The Rock" Johnson

Your new name is:
Dwayne "The Rock" Johnson Mk II

Zauważ, że cool_name jest wynikiem konkatenacji trzech łańcuchów - first_name, "The Rock" i last_name. Dalej w kodzie można zobaczyć, jak modyfikujemy cool_name poprzez dołącznie do niego " Mk II".

Sprawdzanie długości

Aby sprawdzić ile znaków znajduje się w łancuchu używamy tak zwanej metody size. O funkcjach i metodach będziemy mówić więcej w dalszej części kursu, gdyż są one bardzo ważnym pojęciem.

Zobaczmy jak wykorzystać metodę size w praktyce. Rozważmy następujący przykład z wejściem Johnny:

Program liczący długość imienia
#include <iostream>
#include <string>

int main()
{
std::string name;
std::cout << "Enter your name: ";
std::cin >> name;

std::cout << "\nWelcome, " << name << "!\n";
std::cout << "Your name has " << name.size() << " characters.\n";
}
Result
Welcome, Johnny!
Your name has 6 characters.

Metodę size wywołujemy na zmiennej name w następujący sposób: name.size(). Symbol . wskazuje, że mamy dostęp do czegoś na naszej zmiennej name. size jest nazwą metody, do której uzyskujemy dostęp.

Użycie nawiasów () * wywołuje* metodę size. Ta zwraca nam całkowitą liczbę znaków w napisie.

Te pojęcia nie są teraz kluczowe do zapamiętania, ale zobaczysz je później w lekcjach Funkcje i Metody; po prostu zapamiętaj jak ich używać.

Dla przypomnienia, określamy zmienną (name), następnie piszemy size po kropce, a potem puste nawiasy okrągłe:

Wywołanie metody size
name.size()

Konwersja pomięzdy liczbami i tekstem

Liczby i łańcuchy nie mogą być swobodnie konwertowane na siebie bez specjalnych funkcji, która robią to za nas. Dzieje się tak dlatego, że typy liczbowe i typy łańcuchów w C++ są zdecydowanie różne i nie są ogólnie kompatybilne. Choć może to być denerwujące, jest to w rzeczywistości bardzo ważne dla tworzenia kodu wolnego od błędów.

53
"53"

Pierwszą wartością jest liczba 53. Reprezentuje ona wartość, na której możemy wykonywać operacje matematyczne. Druga wartość to tekst składający się ze znaków '5' i '3'. Nie możemy wykonywać operacji matematycznych na łańcuchach; raczej, operacje na łańcuchach, które możemy wykonać to konkatenacje.

Następujące kawałki kodu to nieudolne i niepoprawne (kończące się błędem kompilacji) próby konwersji między łańcuchami a liczbami:

❌ Przypisywanie zmiennej liczbowej do łańcucha
int number = 53;
std::string number_in_str = number; // Błąd

Aby przekonwertować z typu liczbowego (np. int czy float) na typ łańcuchowy, musimy użyć funkcji std::to_string.

✔ Konwersja liczby na napis
int number = 53;
std::string number_in_str = std::to_string(number);

W ten sam sposób, jeśli mamy wewnątrz łańcucha znaków zapisaną liczbę, możemy ją przekonwertować na inta za pomocą std::stoi (od ang.: string to int) oraz typu float za pomocą std::stof (od ang.: string to float):

Konwersja std::string na int
std::string number_in_str = "53";
int number = std::stoi(number_in_str);

Podsumowanie

W tej lekcji dowiedzieliśmy się o typie std::string, który służy do przechowywania i manipulowania sekwencjami znaków.

dobra rada

Zobacz następujące podlekcje, aby zapoznać się lepiej z łańcuchami znaków: