Dostęp do znaków
Istnieją dwa prawie identyczne sposoby uzyskiwania dostępu do znaków w ciągu znaków. Łatwiejszą w użyciu i szybszą wersją jest przeciążony operator[]:
char& string::operator[] (size_type nIndex) const char& string::operator[] (size_type nIndex) const- Obie te funkcje zwracają znak o indeksie nIndex
- Przekazanie nieprawidłowego indeksu skutkuje niezdefiniowaniem zachowanie
- Ponieważ char& jest typem zwracanym, możesz go użyć do edycji znaków w tablicy
Przykładowy kod: std::string sSource{ "abcdefg" };
std::cout << sSource[5] << '\n';
sSource[5] = 'X';
std::cout << sSource << '\n';
Wyjście: f
abcdeXg
|
Istnieje również wersja bez operatora. Ta wersja jest wolniejsza, ponieważ używa wyjątków do sprawdzania, czy nIndex jest prawidłowy. Jeśli nie jesteś pewien, czy nIndex jest poprawny, powinieneś użyć tej wersji, aby uzyskać dostęp do tablicy:
char& string::at (size_type nIndex) const char& string::at (size_type nIndex) const- Obie te funkcje zwracają znak o indeksie nIndex
- Przekazanie nieprawidłowego indeksu skutkuje out_of_range wyjątek
- Ponieważ char& jest typem zwracanym, możesz go użyć do edycji znaków w tablicy
Przykładowy kod: std::string sSource{ "abcdefg" };
std::cout << sSource.at(5) << '\n';
sSource.at(5) = 'X';
std::cout << sSource << '\n';
Wyjście: f
abcdeXg
|
Konwersja na tablice w stylu C
Wiele funkcji (w tym wszystkie funkcje C) oczekuje, że ciągi znaków będą sformatowane w stylu C, a nie std::string. Z tego powodu std::string udostępnia 3 różne sposoby konwersji std::string na ciągi w stylu C.
const char* string::c_str () const- Zwraca zawartość ciągu jako stały ciąg w stylu C
- Dodawany jest terminator zerowy
- Łańcuch w stylu C jest własnością std::string i nie powinien być usuwany
Przykładowy kod: #include <cstring>
std::string sSource{ "abcdefg" };
std::cout << std::strlen(sSource.c_str());
Wyjście: 7
|
const char* string::data () const- Zwraca zawartość ciągu jako stały ciąg w stylu C
- Dodawany jest terminator zerowy. Ta funkcja wykonuje tę samą akcję, co
c_str() - Łańcuch w stylu C jest własnością std::string i nie powinien być usuwany
Przykładowy kod: #include <cstring>
std::string sSource{ "abcdefg" };
const char* szString{ "abcdefg" };
// memcmp compares the first n characters of two C-style strings and returns 0 if they are equal
if (std::memcmp(sSource.data(), szString, sSource.length()) == 0)
std::cout << "The strings are equal";
else
std::cout << "The strings are not equal";
Wyjście: The strings are equal
|
size_type string::copy(char* szBuf, size_type nLength, size_type nIndex = 0) const- Oba warianty kopiują co najwyżej nLength znaków ciągu do szBuf, zaczynając od znaku nIndex
- Zwracana jest liczba skopiowanych znaków
- Null nie jest dołączana. Do wywołującego należy upewnienie się, że szBuf jest zainicjowany na NULL lub zakończenie łańcucha przy użyciu zwróconej długości
- Wywołujący jest odpowiedzialny za nieprzepełnienie szBuf
Przykładowy kod: std::string sSource{ "sphinx of black quartz, judge my vow" };
char szBuf[20];
int nLength{ static_cast<int>(sSource.copy(szBuf, 5, 10)) };
szBuf[nLength] = '\0'; // Make sure we terminate the string in the buffer
std::cout << szBuf << '\n';
Wyjście: black
|
Tej funkcji należy unikać tam, gdzie to możliwe, ponieważ jest stosunkowo niebezpieczna (ponieważ to do wywołującego należy zapewnienie zakończenia zerowego i uniknięcie przepełnienia bufora).