C++/String: Różnice pomiędzy wersjami

Z Wikibooks, biblioteki wolnych podręczników.
< C++
Usunięta treść Dodana treść
Nie podano opisu zmian
Lethern (dyskusja | edycje)
poprawki
Linia 1: Linia 1:
== String ==
== String ==


Napisy w stylu języka C są częstą przyczyną błędów a na dodatek ich używanie jest dosyć kłopotliwe. Nic wiec dziwnego że biblioteka standardowa posiada zaimplementowaną uogólnioną klasę napisów zwaną string. Taka klasa daje jednolity, niezależny od systemu i bezpieczny interfejs do manipulowania napisami.
Łańcuchy znaków w stylu języka C są częstą przyczyną błędów programu, a na dodatek ich używanie jest dosyć kłopotliwe. Nic wiec dziwnego, że biblioteka standardowa posiada zaimplementowaną uogólnioną klasę napisów zwaną <tt>string</tt>. Taka klasa daje jednolity, niezależny od systemu i bezpieczny interfejs do manipulowania napisami.


Aby móc korzystać z klasy string należy dołączyć plik nagłówkowy:
Aby móc korzystać z klasy <tt>string</tt> należy dołączyć plik nagłówkowy:
<source lang="cpp">
#include <string>
</source>


Tworzenie nowych obiektów tego typu wygląda następująco:
#include <string>
<source lang="cpp">

string napis1;
Tworzyć nowe obiekty tego typu możemy następująco:
napis1 = "text";

string napis1;
napis1 = "text";
string napis2( "text" );
string napis2( "text" );
string napis3 = "text";
string napis3 = "text";
cout << napis1 << endl
cout << napis1 << '\n'
<< napis2 << endl
<< napis2 << '\n'
<< napis3 << endl;
<< napis3 << '\n';
string napis4(10,'X');
string napis4(10,'X');
cout << napis4;
cout << napis4;
</source>


Uwaga:
Uwaga:<br />
Aby kompilator widział typ "string" należy powiadomić go, w jakiej przestrzeni nazw ten typ się znajduje, np. w ten sposób:
Aby kompilator widział typ <tt>string</tt>, należy powiadomić go w jakiej przestrzeni nazw ten typ się znajduje:


<code>using namespace std;</code>
<source lang="cpp">using std::string;</source>


lub ogólnie:
lub bardziej elegancko i bezpieczniej:


<code>using std::string;</code>
<source lang="cpp">using namespace std;</source>


Klasa string ma zdefiniowanych wiele operatorów, co ułatwia niektóre działania na napisach. Dla przykładu, dawniej aby skopiować napis z jednej zmiennej do drugiej, trzeba było używać dodatkowej funkcji <tt>strcpy()</tt>. W przypadku klasy <tt>string</tt> wystarczy operator przypisania '=' :
<source lang="cpp">
string a, b;
a = '1';
b = '2';
a = b;
cout << a;
</source>
Możemy z powodzeniem używać także operatorów: ==, !=, +, <, > oraz indeksowego []:
<source lang="cpp">
string a,b,c;
a = "gosia";
b = "iza";
c = "gosia";


// porównywanie napisów
Powyższy kod da w wyniku:
if (a == c) cout << "a i c sa takie same\n";


if (a != b) cout << "a i b sa rozne\n" ;
text
text
text
XXXXXXXXXX


// porządek leksykograficzny
Klasa string ma zdefiniowanych bardzo wiele operatorów, co ułatwia niektóre działania na napisach. Dla przykładu dawniej aby skopiować napis do innego z napisu trzeba było używać funkcji strcpy(). W implementacji klasy string wystarczy operator przypisania '=' :
cout << "napis a ("<<a<<") poprzedza napis b("<<b<<"): ";
if (a < b) cout << "prawda\n";
else cout << "nieprawda\n";


// łączenie łańcuchów
string a, b;
a = '1';
a = "mal"+ a;
b = '2';
a = b;
cout << a;
Mamy też takie operatory jak ==, !=, + i indeksowy []:


cout << "napis a ("<<a<<") poprzedza napis b("<<b<<"): ";
string a,b,c;
if (a < b) cout << "prawda\n";
a = "Europa";
else cout << "nieprawda\n";
b = "Afryka";

c = "Europa";
// modyfikacja
b[0] = '_';
if (a == c)

cout << "takie same\n";
cout << "zmieniony wyraz b: "<<b<<'\n';
</source>
if (a > b)
cout << "napis a jest wiekszy\n";
else
cout << "napis a nie jest wiekszy\n";
b = b + 'a';
if (a > b)
cout << "napis a jest wiekszy\n";
else
cout << "napis a nie jest wiekszy\n";
if (a != b)
cout << "rozne\n" ;
b[0] = '_';
cout << b;


Po czym w konsoli zobaczymy:
Po czym w konsoli zobaczymy:
a i c sa takie same
a i b sa rozne
napis a (gosia) poprzedza napis b(iza): prawda
napis a (malgosia) poprzedza napis b(iza): nieprawda
zmieniony wyraz b: _za


Jak widać, manipulacje obiektami <tt>string</tt> są intuicyjne. Oprócz wygodnych w stosowaniu operatorów, klasa string posiada jeszcze więcej metod.
takie same
napis a jest wiekszy
napis a jest wiekszy
rozne
_frykaa

Jak widać manipulacje obiektami string są bardzo wygodne. Oprócz wygodnych w stosowaniu operatorów klasa string posiada jeszcze więcej metod.


<table weight="100%" border="0" cellspacing="3" cellpadding="6px" >
<table weight="100%" border="0" cellspacing="3" cellpadding="6px" >
Linia 93: Linia 88:
<tr><td><tt>size(),length()</tt></td><td>Zwraca ilość znaków w napisie.</td></tr>
<tr><td><tt>size(),length()</tt></td><td>Zwraca ilość znaków w napisie.</td></tr>
<tr><td><tt>at()</tt></td><td>Zwraca znak o podanym położeniu, podobnie jak operator [] z tym że ta metoda jest bezpieczniejsza, zapobiega wyjściu poza zakres.</td></tr>
<tr><td><tt>at()</tt></td><td>Zwraca znak o podanym położeniu, podobnie jak operator [] z tym że ta metoda jest bezpieczniejsza, zapobiega wyjściu poza zakres.</td></tr>
<tr><td><tt>clear(),erase()</tt></td><td>Usuwa wszystkie znaki z napisu, erase() może usuwać wybrane znaki.</td></tr>
<tr><td><tt>clear()</tt></td><td>Usuwa wszystkie znaki z napisu.</td></tr>
<tr><td><tt>find()</tt></td><td>Znajduje podciąg w ciągu, są też bardziej rozbudowane funkcje tego typu.</td></tr>
<tr><td><tt>erase(...)</tt></td><td>clear() Usuwa wybrane znaki.</td></tr>
<tr><td><tt>find(...)</tt></td><td>Znajduje podciąg w ciągu, są też bardziej rozbudowane funkcje tego typu.</td></tr>
<tr><td><tt>swap()</tt></td><td>Zamienia miejscami dwa stringi, a staje się b, a b staje się a.</td></tr>
<tr><td><tt>swap(...)</tt></td><td>Zamienia miejscami dwa stringi, a staje się b, a b staje się a.</td></tr>
<tr><td><tt>substr( int ''start_index'', int ''długość'' )</tt></td><td>Zwraca podciąg na podstawie indeksu początkowego i długości podciągu.</td></tr>
<tr><td><tt>substr(... )</tt></td><td>Zwraca podciąg na podstawie indeksu początkowego i długości podciągu.</td></tr>
<tr><td><tt>append()</tt></td><td>Dodaje zadany napis na końcu istniejącego ciągu.</td></tr>
<tr><td><tt>append(...)</tt></td><td>Dodaje zadany napis na końcu istniejącego ciągu.</td></tr>
<tr><td><tt>c_str()</tt></td><td>Zwraca napis w stylu języka C (stały wskaźnik do pierwszego elementu).</td></tr>
<tr><td><tt>c_str()</tt></td><td>Zwraca napis w stylu języka C (stały wskaźnik typu <tt>const char*</tt>).</td></tr>
</table>
</table>


{{TODO|omówić wymienione wyżej metody}}
Omówione dotychczas operatory i metody to tylko część dostępnych, tu wymieniłem tylko te najczęściej używane. Teraz przedstawię różnice jakie występują między bibliotekami C a C++ w obsłudze napisów.


Omówione dotychczas operatory i metody to tylko część dostępnych; wymienione zostały tylko te najczęściej używane. Teraz przedstawię różnice jakie występują między C a C++ w obsłudze napisów.
<table weight="100%" border="0" cellspacing="3" cellpadding="6px" >

<table border="0" cellspacing="3" cellpadding="6px" >
<tr><td><b>C</b></td><td><b>C++</b></td></tr>
<tr><td><b>C</b></td><td><b>C++</b></td></tr>
<tr><td><tt>strcpy(a,b) </tt></td><td><tt> a = b</tt></td></tr>
<tr><td><tt>strcpy(a,b) </tt></td><td><tt> a = b</tt></td></tr>
Linia 113: Linia 111:


<noinclude>
<noinclude>

{{Nawigacja|C++|
{{Nawigacja|C++|
[[C++:Filozofia STL|Filozofia STL]]|
[[C++:Filozofia STL|Filozofia STL]]|

Wersja z 11:03, 29 wrz 2010

String

Łańcuchy znaków w stylu języka C są częstą przyczyną błędów programu, a na dodatek ich używanie jest dosyć kłopotliwe. Nic wiec dziwnego, że biblioteka standardowa posiada zaimplementowaną uogólnioną klasę napisów zwaną string. Taka klasa daje jednolity, niezależny od systemu i bezpieczny interfejs do manipulowania napisami.

Aby móc korzystać z klasy string należy dołączyć plik nagłówkowy:

#include <string>

Tworzenie nowych obiektów tego typu wygląda następująco:

string napis1;
napis1 = "text";
 
string napis2( "text" );
     
string napis3 = "text";
     
cout << napis1 << '\n'
     << napis2 << '\n'
     << napis3 << '\n';
          
string napis4(10,'X');
     
cout << napis4;

Uwaga:
Aby kompilator widział typ string, należy powiadomić go w jakiej przestrzeni nazw ten typ się znajduje:

using std::string;

lub ogólnie:

using namespace std;

Klasa string ma zdefiniowanych wiele operatorów, co ułatwia niektóre działania na napisach. Dla przykładu, dawniej aby skopiować napis z jednej zmiennej do drugiej, trzeba było używać dodatkowej funkcji strcpy(). W przypadku klasy string wystarczy operator przypisania '=' :

string a, b;
a = '1';
b = '2';
a = b;
cout << a;

Możemy z powodzeniem używać także operatorów: ==, !=, +, <, > oraz indeksowego []:

string a,b,c;
a = "gosia";
b = "iza";
c = "gosia";

// porównywanie napisów
if (a == c) cout << "a i c sa takie same\n";

if (a != b) cout << "a i b sa rozne\n" ;

// porządek leksykograficzny
cout << "napis a ("<<a<<") poprzedza napis b("<<b<<"): ";
if (a < b) cout << "prawda\n";
else cout << "nieprawda\n";

// łączenie łańcuchów
a = "mal"+ a;

cout << "napis a ("<<a<<") poprzedza napis b("<<b<<"): ";
if (a < b) cout << "prawda\n";
else cout << "nieprawda\n";

// modyfikacja
b[0] = '_';

cout << "zmieniony wyraz b: "<<b<<'\n';

Po czym w konsoli zobaczymy:

a i c sa takie same
a i b sa rozne
napis a (gosia) poprzedza napis b(iza): prawda
napis a (malgosia) poprzedza napis b(iza): nieprawda
zmieniony wyraz b: _za

Jak widać, manipulacje obiektami string są intuicyjne. Oprócz wygodnych w stosowaniu operatorów, klasa string posiada jeszcze więcej metod.

MetodaOpis
empty()Zwraca wartość true jeżeli napis jest pusty.
size(),length()Zwraca ilość znaków w napisie.
at()Zwraca znak o podanym położeniu, podobnie jak operator [] z tym że ta metoda jest bezpieczniejsza, zapobiega wyjściu poza zakres.
clear()Usuwa wszystkie znaki z napisu.
erase(...)clear() Usuwa wybrane znaki.
find(...)Znajduje podciąg w ciągu, są też bardziej rozbudowane funkcje tego typu.
swap(...)Zamienia miejscami dwa stringi, a staje się b, a b staje się a.
substr(... )Zwraca podciąg na podstawie indeksu początkowego i długości podciągu.
append(...)Dodaje zadany napis na końcu istniejącego ciągu.
c_str()Zwraca napis w stylu języka C (stały wskaźnik typu const char*).

Omówione dotychczas operatory i metody to tylko część dostępnych; wymienione zostały tylko te najczęściej używane. Teraz przedstawię różnice jakie występują między C a C++ w obsłudze napisów.

CC++
strcpy(a,b) a = b
strcmp(a,b) a == b
strcat(a,b) a += b
strlen(a) a.size()
strstr(a,b) a.find(b)