Funkcje związane z operacjami na łańcuchach znaków

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 6271 razy

Czas troszeczkę poświęcić uwagi na tablice znaków char* i to zarówno te statycznie jak i dynamicznie tworzone. Umownie stosuje się w takich tablicach zapis danych tekstowych, gdzie jeden element tablicy oznacza pojedynczy znak tekstu. Na końcu tablicy musi znajdować się dodatkowy element, którego wartość musi być równa zero, co oznacza koniec tekstu.

W pliku nagłówkowym string.h (nie mylić z string) znajduje się zbiór funkcji związanych z operacjami wykonywanymi na łańcuchach znaków i nie tylko, poniżej zamieszczam poszczególne z nich:

Funkcje kopiujące

char * memcpy(char * destination, const char * source);

Funkcja kopiuje dane z source (źródła) do destination (celu):

char tekst[20]; // cel, do którego skopiowany zostanie tekst char tekst2[] = "cos tam napisalem i teraz to przekopiuje do zmiennej \apostekst\apos"; // źródło memcpy((void*)tekst, (void*)tekst2, sizeof(tekst) / sizeof(char) /* rozmiar w bajtach musi być podany */); // kopiowanko tekst[19] = 0; // ostatni element musi być równy 0 cout<<tekst<<endl<<endl; // wyświetlanie skopiowanych danych struct point2d{ // tworzę przykładową deklarację struktury int x; int y; char description[100]; }; point2d s1 = {100, 200, "opis"}; point2d s2; memcpy(&s2, &s1, sizeof(point2d)); cout<<s2.x<<" "<<s2.y<<" "<<s2.description<<endl<<endl;

Wynik działania:

cos tam napisalem i
100 200 opis

char * memmove(char * destination, const char * source);

Ta funkcja przenosi wartości podanej liczby bajtów z źródła do wskazanego miejsca.

char * strcpy(char * destination, const char * source);

Kopiowanie ciągu znaków z source (źródła) do destination (celu).

char tekst[] = "cos tam do skopiowania"; char tekst2[200]; strcpy(tekst2, tekst); cout<<tekst2;

Wynik działania:

cos tam do skopiowania

char * strncpy( char * destination, const char * source, size_t num );

Funkcja ta umożliwia skopiowanie num elementów znaków z source (źródła) do destination (celu).

char tekst[] = "cos tam do skopiowania"; char tekst2[200]; strncpy(tekst2, tekst, 7); tekst2[7] = 0; // tutaj ręcznie muszę dodać 0 na końcu, aby wiadome było, że tam kończy się tekst cout<<tekst2;

Wynik działania:

cos tam

Funkcje związane z łączeniem dwóch ciągów znaków

char * strcat( char * destination, const char * source );

Funkcja dodaje łańcuch znaków z source (źródła) do destination (celu).

char tekst[200]; strcpy(tekst, "Wczytywanie tekstu: "); strcat(tekst,"dopisanie tekstu;"); strcat(tekst," dopisanie drugiego tekstu;"); cout<<tekst;

Wynik działania:

Wczytywanie tekstu: dopisanie tekstu; dopisanie drugiego tekstu;

char * strncat( char * destination, const char * source, size_t num );

Kopiuje num początkowych znaków z source (źródła) do destination (celu) dodając na końcu znak końca tekstu.

char tekst[200]; strcpy(tekst, "Wczytywanie tekstu: "); strncat(tekst,"dopisanie drugiego tekstu;",9); cout<<tekst;

Wynik działania:

Wczytanie tekstu: dopisanie

Funkcje porównujące

int memcmp( const void * ptr1, const void * ptr2, size_t num );

Porównuje pierwszych num bajtów pamięci, na które wskazują wskaźniki ptr1 i tr2. Zwracana wartość jest równa zero, gdy wszystkie bajty porównywanych bloków pamięci są sobie równe, mniejszą od zera, gdy pierwszy napotkany bajt z ptr1 zawiera wartość mniejszą od odpowiadającego mu bujtu z ptr2 i wartość większą od zera w przeciwnym przypadku.

int w1[] = {1, 2, 3, 4, 5}; int w2[] = {5, 2, 3, 4, 1}; if(!memcmp(w1, w1,5)){ // to oczywiście zwróci zero a negacja zera to prawda if(memcmp(w2,w1,5)>0) // to zwróci wartość większą od zera (4) cout<<"w tablicy w2 znaleziono bajt wiekszy od bajtu w tablicy w1"; }

Wynik działania:

w tablicy w2 znaleziono bajt wiekszy od bajtu w tablicy w1

int strcmp( const char * str1, const char * str2 );

Porównuje dwa ciągi znaków str1 i str2 i zwraca zero gdy te są sobie równe. Ma tutaj miejsce porównywanie bitowe.

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char str1[] = "bąk"; char str2[] = "bok"; if(!strcmp(str1,str1)){ // to oczywiście będzie prawdą if(strcmp(str1,str2)<0){ cout<<str1<<"<"<<str2; }else if(strcmp(str1,str2)>0){ cout<<str1<<">"<<str2; } }

Wynik działania:

bąk>bok

int stricmp(const char *str1, const char * str2 );

Porównuje dwa ciągi znaków str1 i str2 ignorując wielkość liter.

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char str1[] = "BOK"; char str2[] = "bok"; if(!strcmp(str1,str1)){ // to oczywiście będzie prawdą if(stricmp(str1,str2)<0){ cout<<str1<<"<"<<str2; }else if(strcmp(str1,str2)>0){ cout<<str1<<">"<<str2; }else{ cout<<str1<<"="<<str2; } }

Wynik działania:

BOK=bok

int strcoll( const char * str1, const char * str2 );

Porównuje dwa ciągi na podstawie ustawień lokalnych, które można ustawić za pomocą funkcji setlocale z pierwszym parametrem ustawionym na LC_COLLATE a drugim określającym kraj, którego znaki mają być brane pod uwagę (w tym przypadku wypadałoby, aby podać wartość "Polish").

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char str1[] = "bąk"; char str2[] = "bok"; if(!strcoll(str1,str1)){ // to oczywiście będzie prawdą if(strcoll(str1,str2)<0){ cout<<str1<<"<"<<str2; }else if(strcoll(str1,str2)>0){ cout<<str1<<">"<<str2; } }

Wynik działania:

bąk<bok

int stricoll( const char * str1, const char * str2 );

Porównuje dwa ciągi na podstawie ustawień lokalnych, które można ustawić za pomocą funkcji setlocale z pierwszym parametrem ustawionym na LC_COLLATE a drugim określającym kraj, którego znaki mają być brane pod uwagę (w tym przypadku wypadałoby, aby podać wartość "Polish"). Funkcja ta nie rozróżnia wielkości liter.

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char str1[] = "bąk"; char str2[] = "BĄK"; if(!strcoll(str1,str1)){ // to oczywiście będzie prawdą if(_stricoll(str1,str2)<0){ cout<<str1<<"<"<<str2; }else if(_stricoll(str1,str2)>0){ cout<<str1<<">"<<str2; }else{ cout<<str1<<"="<<str2; } }

Wynik działania:

bąk=BĄK

int strncmp( const char * str1, const char * str2, size_t num );

Porównuje bitowo pierwszych num elementów ciągów str1 i str2.

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char str1[] = "bąki"; char str2[] = "bąk"; if(strcmp(str1,str2)){ // to oczywiście będzie prawdą if(strncmp(str1,str2,3)<0){ cout<<str1<<"<"<<str2; }else if(strncmp(str1,str2,3)>0){ cout<<str1<<">"<<str2; }else{ cout<<"pierwsze trzy znaki: "<<str1<<" są równe pierwszym trzem znakom "<< str2; } }

Wynik działania:

pierwsze trzy znaki: bąki są równe pierwszym trzem znakom bąk

Przeszukiwanie ciągu znaków

const void * memchr( const void * ptr, int value, size_t num ); void * memchr ( void * ptr, int value, size_t num );

Przeszukuje pierwszych num bajtów bloku pamięci w poszukiwaniu wystąpienia wartości value, gdy ta zostanie napotkana, funkcja zwraca wskaźnik do miejsca wystąpienia, w przeciwnym przypadku, gdy owa wartość nie zostanie odnaleziona funkcja zwraca NULL (czyli 0)

char t[] = "jakis tam tekst"; char *pt=NULL; pt = (char*) memchr(t, 's',strlen(t)); if(pt) cout<<pt;

Wynik działania:

s tam tekst

const char * strchr( const char * str, int character ); char * strchr ( char * str, int character );

Znajduje w ciągu znaków str podany znak character i zwraca wskaźnik do pierwszego miejsca jego wystąpienia, lub NULL.

char t[] = "jakis tam tekst"; char *pt=NULL; pt = strchr(t, 's'); if(pt) cout<<pt;

Wynik działania:

s tam tekst

size_t strcspn( const char * str1, const char * str2 );

Przeszukuje ciąg znaków str1 do momentu znalezienia w tekście jednego z znaków zawartych w str2 i zwraca położenie tego znaku, jeżeli nie znaleziono żadnego znaku, wtedy funkcja zwróci rozmiar ciągu znaków str1.

char t[] = "2*3+1"; char search_key[] = "*+"; size_t size = strcspn(t, search_key); cout<<t + size;

Wynik działania:

*3+1

const char * strpbrk( const char * str1, const char * str2 ); char * strpbrk( char * str1, const char * str2 );

Przeszukuje str1 do momentu znalezienia jednego z znaków zawartych w str2 i zwraca wskaźnik pierwszego wystąpienia dopasowania, w przeciwnym razie zwraca NULL (czyli 0).

char t[] = "2*3+1"; char search_key[] = "*+"; char *pt = strcspn(t, search_key); if(pt) cout<<pt;

Wynik działania:

*3+1

const char * strrchr( const char * str, int character ); char * strrchr( char * str, int character );

Przeszukuje od końca str do momentu znalezienia pierwszego wystąpienia znaku character i zwraca wskaźnik do tego miejsca, jeżeli znak character nie występuje w str to zwraca NULL (czyli 0).

char t[] = "jakis tam tekst"; char *pt=NULL; pt = strrchr(t, 's'); if(pt) cout<<pt;

Wynik działania:

st

size_t strspn( const char * str1, const char * str2 );

Przeszukuje str1 od początku i znajduje długość ciągu, który składa się z znaków zawartych w str2, jeżeli str1 zaczyna się od znaku, który nie występuje w str2 to zwrócone zostanie 0.

char t[] = "231+234"; char search_key[] = "1234567890"; size_t size = strspn(t, search_key); t[size]=NULL; cout<<t;

Wynik działania:

231

const char * strstr( const char * str1, const char * str2 ); char * strstr( char * str1, const char * str2 );

Przeszukuje str1 w poszukiwaniu miejsca wystąpienia ciągu znaków str2 i zwraca wskaźnik do pierwszego takiego wystąpienia, w przeciwnym przypadku, gdy str2 nie występuje w str1 funkcja zwraca NULL (czyli 0).

char t[] = "Ala ma kota"; char search[] = "ma"; char *pt = strstr(t, search); if(pt) cout<<pt;

Wynik działania:

ma kota

char * strtok( char * str, const char * delimiters );

Dzieli w kolejnych wywołaniach str na części, gdzie podział odbywa się w miejscach wywołanych przez wystąpienie jednego z znaków delimiters.

char t[] ="2*3- 5"; char * pt; pt = strtok(t," *-"); while(pt != NULL) { cout<<pt<<endl; pt = strtok(NULL, " ,.-"); }

Funkcje konwertujące ciąg znaków

char * _strrev( char * str )

Odwraca kolejność liter w ciągu znaku str i zwraca wskaźnik do odwróconego ciągu znaków str.

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char text[] = "Jakiś tekst do odwrócenia"; char *pt = _strrev(text); cout<<pt<<" "<<text<<" ";

Wynik działania:

ainecórwdo od tsket śikaJ ainecórwdo od tsket śikaJ

char * strupr( char * str ); char * _strupr( char * str );

Zamienia małe litery zawarte w str na duże.

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char text[] = "Tekst do zmiany"; char *pt = _strupr(text); cout<<pt<<" "<<text<<" ";

Wynik działania:

TEKST DO ZMIANY TEKST DO ZMIANY

char * strlwr( char * str ); char * _strlwr( char * str );

Zamienia duże litery zawarte w str na małe.

setlocale(LC_COLLATE,"Polish"); setlocale(LC_CTYPE,"Polish"); char text[] = "Tekst do zmiany"; char *pt = _strlwr(text); cout<<pt<<" "<<text<<" ";

Wynik działania:

tekst do zmiany tekst do zmiany

Pozostałe funkcje

void * memset(void * ptr, int value, size_t num);

Wypełnia blok pamięci o długości num bajtów, na który wskazuje zmienna ptr wartościami value (przyjmuje jako argument int, ale konwertuje value na unsigned char).

int k[50]; memset((void*)k, 0, sizeof(k) / sizeof(char)); for(int i = 0; i < sizeof(k) / sizeof(int); i++){ cout<<k[i]<<" "; }

Wynik działania:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

size_t strlen(char* str);

Zwraca długość ciągu znaków zawartych w str. Funkcja zadziała prawidłowo jedynie wtedy, gdy wskaźnik ciąg znaków zostanie poprawnie zakończony znakiem terminatora czyli NULL (0).

char t[] = "Jakiś tam tekst"; cout<<"długość tekstu: "<< strlen(t);

Wynik działania:

15

Zadeklarowane typy danych i makra

Wewnątrz pliku nagłówkowego znajdują się deklaracje makr i typów danych:

#define NULL 0 typedef unsigned int size_t;
Propozycje książek