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

Stronę tą wyświetlono już: 223 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

Listing 1
  1. char * memcpy(char * destination, const char * source);

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

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

Wynik działania:

cos tam napisalem i
100 200 opis

Listing 3
  1. char * memmove(char * destination, const char * source);

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

Listing 4
  1. char * strcpy(char * destination, const char * source);

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

Listing 5
  1. char tekst[] = "cos tam do skopiowania";
  2. char tekst2[200];
  3. strcpy(tekst2, tekst);
  4. cout<<tekst2;

Wynik działania:

cos tam do skopiowania

Listing 6
  1. 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).

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

Wynik działania:

cos tam

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

Listing 8
  1. char * strcat( char * destination, const char * source );

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

Listing 9
  1. char tekst[200];
  2. strcpy(tekst, "Wczytywanie tekstu: ");
  3. strcat(tekst,"dopisanie tekstu;");
  4. strcat(tekst," dopisanie drugiego tekstu;");
  5. cout<<tekst;

Wynik działania:

Wczytywanie tekstu: dopisanie tekstu; dopisanie drugiego tekstu;

Listing 10
  1. 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.

Listing 11
  1. char tekst[200];
  2. strcpy(tekst, "Wczytywanie tekstu: ");
  3. strncat(tekst,"dopisanie drugiego tekstu;",9);
  4. cout<<tekst;

Wynik działania:

Wczytanie tekstu: dopisanie

Funkcje porównujące

Listing 12
  1. 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.

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

Wynik działania:

w tablicy w2 znaleziono bajt wiekszy od bajtu w tablicy w1

Listing 14
  1. 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.

Listing 15
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char str1[] = "bąk";
  4. char str2[] = "bok";
  5. if(!strcmp(str1,str1)){ // to oczywiście będzie prawdą
  6. if(strcmp(str1,str2)<0){
  7. cout<<str1<<"<"<<str2;
  8. }else if(strcmp(str1,str2)>0){
  9. cout<<str1<<">"<<str2;
  10. }
  11. }

Wynik działania:

bąk>bok

Listing 16
  1. int stricmp(const char *str1, const char * str2 );

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

Listing 17
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char str1[] = "BOK";
  4. char str2[] = "bok";
  5. if(!strcmp(str1,str1)){ // to oczywiście będzie prawdą
  6. if(stricmp(str1,str2)<0){
  7. cout<<str1<<"<"<<str2;
  8. }else if(strcmp(str1,str2)>0){
  9. cout<<str1<<">"<<str2;
  10. }else{
  11. cout<<str1<<"="<<str2;
  12. }
  13. }

Wynik działania:

BOK=bok

Listing 18
  1. 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").

Listing 19
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char str1[] = "bąk";
  4. char str2[] = "bok";
  5. if(!strcoll(str1,str1)){ // to oczywiście będzie prawdą
  6. if(strcoll(str1,str2)<0){
  7. cout<<str1<<"<"<<str2;
  8. }else if(strcoll(str1,str2)>0){
  9. cout<<str1<<">"<<str2;
  10. }
  11. }

Wynik działania:

bąk<bok

Listing 20
  1. 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.

Listing 21
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char str1[] = "bąk";
  4. char str2[] = "BĄK";
  5. if(!strcoll(str1,str1)){ // to oczywiście będzie prawdą
  6. if(_stricoll(str1,str2)<0){
  7. cout<<str1<<"<"<<str2;
  8. }else if(_stricoll(str1,str2)>0){
  9. cout<<str1<<">"<<str2;
  10. }else{
  11. cout<<str1<<"="<<str2;
  12. }
  13. }

Wynik działania:

bąk=BĄK

Listing 22
  1. int strncmp( const char * str1, const char * str2, size_t num );

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

Listing 23
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char str1[] = "bąki";
  4. char str2[] = "bąk";
  5. if(strcmp(str1,str2)){ // to oczywiście będzie prawdą
  6. if(strncmp(str1,str2,3)<0){
  7. cout<<str1<<"<"<<str2;
  8. }else if(strncmp(str1,str2,3)>0){
  9. cout<<str1<<">"<<str2;
  10. }else{
  11. cout<<"pierwsze trzy znaki: "<<str1<<" są równe pierwszym trzem znakom "<< str2;
  12. }
  13. }

Wynik działania:

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

Przeszukiwanie ciągu znaków

Listing 24
  1. const void * memchr( const void * ptr, int value, size_t num );
  2. 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)

Listing 25
  1. char t[] = "jakis tam tekst";
  2. char *pt=NULL;
  3. pt = (char*) memchr(t, 's',strlen(t));
  4. if(pt)
  5. cout<<pt;

Wynik działania:

s tam tekst

Listing 26
  1. const char * strchr( const char * str, int character );
  2. 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.

Listing 27
  1. char t[] = "jakis tam tekst";
  2. char *pt=NULL;
  3. pt = strchr(t, 's');
  4. if(pt)
  5. cout<<pt;

Wynik działania:

s tam tekst

Listing 28
  1. 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.

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

Wynik działania:

*3+1

Listing 30
  1. const char * strpbrk( const char * str1, const char * str2 );
  2. 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).

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

Wynik działania:

*3+1

Listing 32
  1. const char * strrchr( const char * str, int character );
  2. 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).

Listing 33
  1. char t[] = "jakis tam tekst";
  2. char *pt=NULL;
  3. pt = strrchr(t, 's');
  4. if(pt)
  5. cout<<pt;

Wynik działania:

st

Listing 34
  1. 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.

Listing 35
  1. char t[] = "231+234";
  2. char search_key[] = "1234567890";
  3. size_t size = strspn(t, search_key);
  4. t[size]=NULL;
  5. cout<<t;

Wynik działania:

231

Listing 36
  1. const char * strstr( const char * str1, const char * str2 );
  2. 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).

Listing 37
  1. char t[] = "Ala ma kota";
  2. char search[] = "ma";
  3. char *pt = strstr(t, search);
  4. if(pt)
  5. cout<<pt;

Wynik działania:

ma kota

Listing 38
  1. 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.

Listing 39
  1. char t[] ="2*3- 5";
  2. char * pt;
  3. pt = strtok(t," *-");
  4. while(pt != NULL)
  5. {
  6. cout<<pt<<endl;
  7. pt = strtok(NULL, " ,.-");
  8. }

Funkcje konwertujące ciąg znaków

Listing 40
  1. char * _strrev( char * str )

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

Listing 41
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char text[] = "Jakiś tekst do odwrócenia";
  4. char *pt = _strrev(text);
  5. cout<<pt<<" "<<text<<" ";

Wynik działania:

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

Listing 42
  1. char * strupr( char * str );
  2. char * _strupr( char * str );

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

Listing 43
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char text[] = "Tekst do zmiany";
  4. char *pt = _strupr(text);
  5. cout<<pt<<" "<<text<<" ";

Wynik działania:

TEKST DO ZMIANY TEKST DO ZMIANY

Listing 44
  1. char * strlwr( char * str );
  2. char * _strlwr( char * str );

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

Listing 45
  1. setlocale(LC_COLLATE,"Polish");
  2. setlocale(LC_CTYPE,"Polish");
  3. char text[] = "Tekst do zmiany";
  4. char *pt = _strlwr(text);
  5. cout<<pt<<" "<<text<<" ";

Wynik działania:

tekst do zmiany tekst do zmiany

Pozostałe funkcje

Listing 46
  1. 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).

Listing 47
  1. int k[50];
  2. memset((void*)k, 0, sizeof(k) / sizeof(char));
  3. for(int i = 0; i < sizeof(k) / sizeof(int); i++){
  4. cout<<k[i]<<" ";
  5. }

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 

Listing 48
  1. 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).

Listing 49
  1. char t[] = "Jakiś tam tekst";
  2. 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:

Listing 50
  1. #define NULL 0
  2. typedef unsigned int size_t;

Komentarze