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.
#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.
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.
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:
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.
#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:
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:
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;
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:
#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";
}
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:
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:
- ❌ Niepoprawne
- ❌ Niepoprawne
- ❌ Niepoprawne
- ❌ Niepoprawne
int number = 53;
std::string number_in_str = number; // Błąd
std::string number_in_str = 53; // Błąd
std::string str = "53";
int number = str; // Error
int number = "53"; // Error
Aby przekonwertować z typu liczbowego (np. int czy float) na typ łańcuchowy, musimy użyć funkcji std::to_string.
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):
- 🔵 std::stoi
- 🟣 std::stof
std::string number_in_str = "53";
int number = std::stoi(number_in_str);
std::string number_in_str = "53.5"; // w tekście nie podajemy `f` na końcu
float number = std::stof(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.
Zobacz następujące podlekcje, aby zapoznać się lepiej z łańcuchami znaków: