Programowanie w C Typ wskaźnikowy do typu znakowego i operacje na łańcuchach

Podobne dokumenty
Ćwiczenie nr 6. Poprawne deklaracje takich zmiennych tekstowych mogą wyglądać tak:

int tab[5]; tab[1]; ciągły obszar pamięci, w którym umieszczone są elementy tego samego typu macierz [ ] - dwuargumentowy operator indeksowania

Tablice deklaracja, reprezentacja wewnętrzna

ŁAŃCUCHY W JĘZYKU C/C++

DANE TEKSTOWE W JĘZYKU C/C++ - TABLICE ZNAKOWE

Podstawy programowania w języku C++

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 7- sem.iii. M. Czyżak

Spis treści JĘZYK C - ŁAŃCUCHY ZNAKÓW. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF22

Języki programowania. Przetwarzanie tablic znaków. Część druga. Autorzy Tomasz Xięski Roman Simiński

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

Podstawy programowania 1

Podstawy programowania

Języki programowania obiektowego Nieobiektowe elementy języka C++

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 9 - sem.iii. Dr inż. M. Czyżak

Spis treści JĘZYK C - ŁAŃCUCHY ZNAKÓW. Informatyka 1. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF10Z

Stałe i zmienne znakowe. Stała znakowa: znak

Laboratorium 6: Ciągi znaków. mgr inż. Leszek Ciopiński dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Podstawy Programowania

Podstawy Programowania

Podstawy Programowania. Przetwarzanie napisów, drzewa binarne

Programowanie Proceduralne

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

PODSTAW PROGRAMOWANIA WYKŁAD 7 ŁAŃCUCHY

Podstawy Programowania. Przetwarzanie napisów, drzewa binarne

iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

2 Przygotował: mgr inż. Maciej Lasota

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Wprowadzenie do programowania w języku C

Podstawy programowania w języku C++

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Wskaźniki w C. Anna Gogolińska

Tablice, funkcje - wprowadzenie

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Wyklad 7 Funkcje (c.d.). Tablice jednowymiarowe znaków

Języki i metodyka programowania. Wprowadzenie do języka C

Wstęp do Programowania, laboratorium 02

Spis treści JĘZYK C - TABLICE JEDNOWYMIAROWE, ŁAŃCUCHY ZNAKÓW. Informatyka 1. Instrukcja do pracowni specjalistycznej z przedmiotu

Tablice wielowymiarowe. Przykład tablica 2-wymiarowa. Przykład. Przykład 3-wymiarowy. Tak naprawdę nie istnieją w C! Rozważmy tablicę o rozmiarze 3x2

JĘZYK C - TABLICE DWUWYMIAROWE,

Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Operacje na łańcuchach znaków

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Wstęp do programowania 1

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 2. Karol Tarnowski A-1 p.

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Inicjacja tablicy jednowymiarowej

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 2. Karol Tarnowski A-1 p.

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

Wskaźniki. Informatyka

Podstawy programowania komputerów

Powyższe wyrażenie alokuje 200 lub 400 w zależności od rozmiaru int w danym systemie. Wskaźnik wskazuje na adres pierwszego bajtu pamięci.

Wykład Wskaźniki a tablice jednowymiarowe Arytmetyka wskaźników Dostęp do elementów tablic

Wprowadzenie do tablic znaków (łańcuchów) w ANSI C

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Wykład IV PASCAL - łańcuch znaków, - procedury i funkcje, - sortowanie bąbelkowe

Wykład 6. Operacje na łańcuchach znakowych

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

Wykład II Tablice (wstęp) Przykłady algorytmów Wstęp do języka C/C++

Biblioteka standardowa - operacje wejścia/wyjścia

Funkcja (podprogram) void

wykład III uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - zarządzanie pamięcią, struktury,

Podstawy programowania C. dr. Krystyna Łapin

Wstęp do wskaźników w języku ANSI C

Reprezentacja symboli w komputerze.

Języki i metody programowania I

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Język C zajęcia nr 11. Funkcje

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Informatyka 1. Plan dzisiejszych zajęć. zajęcia nr 11. Elektrotechnika, semestr II rok akademicki 2008/2009

KURS C/C++ WYKŁAD 6. Wskaźniki

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

OPERACJE WEJŚCIA / WYJŚCIA. wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout)

Podstawy programowania w języku C++

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

wykład II uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - funkcje, tablice i wskaźniki wykład II dr Jarosław Mederski Spis

Wskaźniki. Programowanie Proceduralne 1

dr inż. Jarosław Forenc

. Podstawy Programowania 1. Łańcuchy znaków. Arkadiusz Chrobot. 25 listopada 2015

Programowanie Proceduralne

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

Wstęp do programowania

Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Ćwiczenie 1. Podstawy. Wprowadzenie do programowania w języku C. Katedra Metrologii AGH

Elementy języka C. ACprogramislikeafastdanceonanewlywaxeddancefloorbypeople carrying razors.

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Proste typy zmiennych języka C++ *) Zapis 3.4 e-38 jest równoważny zapisowi 3,

Podstawy programowania w języku C++

INFORMATYKA Studia Niestacjonarne Elektrotechnika

Funkcje zawarte w bibliotece < io.h >

Tablice, funkcje, wskaźniki - wprowadzenie

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 3. Karol Tarnowski A-1 p.

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Zasady programowania Dokumentacja

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Podstawy programowania w języku C++

Transkrypt:

Programowanie w C Typ wskaźnikowy do typu znakowego i operacje na łańcuchach Artur Opaliński (pokój E112) e-mail: (p. wykład administracyjny) URL: (p. wykład administracyjny)

Treść wykładu Podstawowe funkcje i operacje na łańcuchach Kopiowanie, Sklejanie Wskaźnik do typu znakowego Zaawansowane operacje na łańcuchach Cięcie Przeszukiwanie Konwersje 2

Wskaźnik do typu znakowego Deklaracja: char *wskaznik1; char* wskaznik2; //najbezpieczniej //uwypukla typ char*wskaznik3; //bez zalet? :-) Uwaga na: char* zmienna1,zmienna2; //zmienna2 jest typu char! Typ zgodny z typem łańcuchowym Może służyć do wskazania na zmienną łańcuchową, lub jej część Stąd nazwa wskaźnika do typu znakowego, gdyż wskazuje wówczas konkretny znak w łańcuchu Zaś pozostałe znaki łańcucha można znaleźć tuż za nim Jeden wskaźnik do typu znakowego może w jednej chwili wskazywać na tylko jeden znak w łańcuchu 3

Wskaźnik do typu znakowego char *wskaznik; char napis[ ]="W stepie szerokim"; Zmienna napis: W s t e p i e s z e r o k i m \0 Zmienna wskaznik: wskaznik nawet nie ma kształtu jak char ;-) 4

Wskaźnik do typu znakowego Wskaźnik do typu znakowego różni się od typu łańcuchowego Wskaźnik do typu znakowego nie zawiera łańcucha znaków Nie rezerwuje na to miejsca w pamięci Może tylko wskazać na istniejący już łańcuch (odwoływać się) Zmienna typu łańcuchowego oczywiście może zawierać łańcuch znaków Rezerwuje na łańcuch miejsce w pamięci Nazwa zmiennej łańcuchowej pozwala się do tego zarezerwowanego miejsca odwoływać Konsekwencja: char *wskaznik; char napis[ ]="W stepie szerokim"; wskaznik=napis; // poprawne, wskaznik wskaze na napis 5 // napis=wskaznik; niepoprawne, napis może wskazywać

Wskaźnik do typu znakowego Inicjalizacja Zmienna wskaźnikowa może być zainicjalizowana i wskazywać znaki: zawarte w zamiennej łańcuchowej: char napis[ ] ="ktorego okiem nawet nie zmierzysz sokolim"; wskaznik=napis; zawarte w stałej łańcuchowej: wskaznik="stan, unies glowe!"; Inicjalizacja podczas deklaracji: char *wskaznik1="stan, unies glowe!"; char napis[12]; char *wskaznik2=napis; pusty // wskazuje na napis, chwilowo 6

Wskaźnik do typu znakowego Podstawowe operacje Wskaźnik może być zainicjalizowany, a mimo to na nic nie wskazywać char *wskaznik=null; Na wskaźnikach można prowadzić operacje arytmetyczne (choć operacje te mają nieco odmienne reguły): char napis[20]="stan, unies glowe!"; char *wskaznik; int dlugoscnapisu; wskaznik=napis; // wskaźnik pokazuje na "Stan, unies glowe!" wskaznik++; // wskaźnik pokazuje na "tan, unies glowe!" wskaźnik=wskaźnik+16; // wskaźnik pokazuje na "!" dlugoscnapisu=wskaznik napis; printf("dlugosc napisu=%d\n", dlugoscnapisu); 7

Wskaźnik do typu znakowego Podobieństwa do tablicy znakowej char napis[] ="Burzac pomniki, oszczedzajcie cokoly. Zawsze moga sie przydac. [S.J.Lec]"; int a; // bardziej elegancko: size_t a; a=strlen("burzac "); // na koncu jest spacja; razem 7 znakow // obecna zawartosc 'napis': puts(napis); printf("%s", napis+a); // co znaczy "+a"? puts(napis+a); // co znaczy "+a"? // jaka czesc napisu zmieniamy? fgets(napis+a, sizeof(napis) - a, stdin); // co znaczy "+a", "-a"? // nowa zawartosc 'napis': puts(napis); printf("%s", napis+a); puts(napis+a); // czym sie roznia: printf("%s", napis+a ); printf("%c", napis[a] ); 8

Wskaźnik do typu znakowego DEMO: debugger + wskaznik.c #include <stdio.h> #include <string.h> main() { char napis[ ]="W stepie szerokim"; // 17 znakow +1 char *wskaznik; puts(napis); //Pod wieloma względami char* jest jak int: wskaznik=null; wskaznik++; printf("wskaznik=%d (jako int)\n", wskaznik); printf("wskaznik=%p (jako wskaznik w hex)\n", wskaznik); 9

Wskaźnik do typu znakowego DEMO: debugger + wskaznik.c (c.d.) wskaznik=napis; // wartosc a wskazywane dane printf("wskazywany tekst=>%s<\n",wskaznik); strcpy(napis,"stan, unies glowe"); printf("wskazywany tekst='%s'\n",wskaznik); /* wskaznik sie NIE zmienil, zmienil sie wskazywany tekst! */ wskaznik=wskaznik+6; // teraz WSKAZNIK sie zmienil puts(wskaznik); // co bedzie? strcpy(wskaznik, "i poloz sie"); //co bedzie? puts(napis); // ryzykowne: zmienic napis[], bez odwolania do niego wskaznik="ktorego okiem nawet sokolim nie zmierzysz"; //gdzie to sie miesci (to 41 znakow+1)? */ puts(wskaznik); 10 puts(napis); }

Operacje na łańcuchach Wiele operacji na łańcuchach prowadzi się z użyciem funkcji zdefiniowanych w pliku nagłówkowym string.h Funkcje te często posługują się wskaźnikiem do typu znakowego Znane: strcpy(), strcat(), strlen() 11

Operacje na łańcuchach Cięcie łańcuchów Kopiowanie ograniczonej ilości znaków: strncpy() char *strncpy(char *restrict s1, const char *restrict s2, size_t n) Jak wyciąć i skopiować tylko pierwsze 5 znaków łańcucha? char zrodlo[20]; char cel[6]; // 5+1=6 strncpy(cel, zrodlo, 5); Jak wyciąć i skopiować tylko ostatnich 5 znaków łańcucha? char *wskaznik; wskaznik=zrodlo+strlen(zrodlo)-5; strcpy(cel,wskaznik); strncpy() wymaga kontroli, czy nie nastąpi nadpisanie 12 pamięci

Operacje na łańcuchach Cięcie łańcuchów Doklejanie ograniczonej ilości znaków: strncat() char *strncat(char *restrict s1, const char *restrict s2, size_t n) Jak wyciąć i dokleić tylko fragment łańcucha? char pelnasciezkapliku[100]; // np.: "C:\Moje Dokumenty\pismo.doc" char komunikat[100]; strcpy(komunikat, "Sciezka wskazuje na dysk "); strncat(komunikat, pelnasciezkapliku, 2); // np. dokleja tylko "C:" 13

Operacje na łańcuchach Przeszukiwanie Szukanie znaku w łańcuchu: strchr() char *strchr(const char *s, int c) Jak znaleźć początek słowa w zdaniu? char zdanie[ ]="Nulla dies sine linea."; char *pozycjaspacji; pozycjaspacji=strchr(zdanie,' '); pozycjaspacji++; // przesuniecie na pierwszy znak za spacja1 // mamy już początek drugiego słowa pozycjaspacji=strchr(pozycjaspacji,' '); //szukamy już tylko za spacja1 //mamy drugą spację w zdaniu zapewne początek trzeciego słowa N u l l a d i e s s i n e l i n e a \0 pozycjaspacji 1 2 3 14

Operacje na łańcuchach Przeszukiwanie Szukanie (pod)łańcucha w łańcuchu: strstr() char *strstr(const char *s1, const char *s2) Jak znaleźć słowo sine w zdaniu? char zdanie[ ]="Nulla dies sine linea."; char slowo[ ]="sine"; char *pozycjaslowa; pozycjaslowa = strstr(zdanie, slowo); if ( pozycjaslowa == NULL ) printf("nie znaleziono slowa %s w zdaniu %s\n", slowo, zdanie); N u l l a d i e s s i n e l i n e a \0 pozycjaslowa 1 15

Operacje na łańcuchach Przeszukiwanie strchr() oraz strstr() zwracają NULL, jeżeli nie znalazły szukanego elementu NULL - specjalna, zarezerwowana do tego celu stała W wielu kompilatorach równa 0 (pośrednio wynika z zaleceń standardu), ale nie należy na tym polegać Stąd po wywołaniu strchr() lub strstr() należy pamiętać o sprawdzeniu, czy nie zwróciły NULL, np: if(strchr(napis, znak) == NULL) printf( Nie znaleziono znaku %c\n, znak); pozycja = strstr(napis1, napis2); if(pozycja == NULL) printf( Nie znaleziono lancucha %s\n, napis2); 16

Podobieństwa i różnice char *i char[ ] char napis1[] ="Burzac pomniki, oszczedzajcie cokoly. Zawsze moga sie przydac. [S.J.Lec]"; char napis2[]="sily"; char *w; w=strstr(napis1, "cokoly"); // wskaznik do slowa printf("szukane slowo rozpoczyna sie pod indeksem:", w-napis1); strcpy(napis1 + w, napis2); strcpy(w, napis2); // niepoprawne. Dlaczego? // co się wydarzy? (c.d.n.) 17

Podobieństwa i różnice char *i char[ ] (c.d.) char *napis3="strzez sie Idow Marcowych" ; // Cezar char *napis4="tego, kto czytal jedna ksiazke"; // Casanova w=strstr(napis3, "Idow"); strcpy(w, napis4); // niepoprawne. Dlaczego? napis3=napis1; w=strstr(napis3, "oszczedzajcie"); strcpy(w, napis4); // ktora zmienna zmieni wartosc? if(sizeof(napis1) < strlen(napis3)) //czy jest miejsce? strcpy(napis1, napis3); strcpy(w, napis1); // niepoprawne; w juz wyznaczylismy w=strstr(napis1, "Idow"); strcpy(w, napis4); // jaka bedzie wartoec lancucha? 18

Operacje na łańcuchach Porównywanie Porównanie dwóch łańcuchów: strcmp() int strcmp(const char *s1, const char *s2) Równość łańcuchów oznacza identyczność wszystkich znaków na tych samych pozycjach, do '\0' włącznie Równość łańcuchów sygnalizowana jest zwróceniem wartości 0 (zero) W przypadku nierówności łańcuchów, zwracana jest różnica między wartością dwóch pierwszych różniących się bajtów s1 i s2 if(strcmp("jablko", "Pomarancza") == 0) puts("lanuchy sa takie same"); else puts("lanuchy sa rozne"); 19

Operacje na łańcuchach Kontrola zbioru znaków Długość początkowej części łańcucha, która składa się wyłącznie z podanych znaków: strspn() size_t strspn(const char *s1, const char *s2) liczbawiodacychbialychznakow = strspn(napis,"\n\t "); lub: liczbawiodacychznakow = strspn(napis,"0123456789+-" ); Długość początkowej części łańcucha, która nie zawiera ani jednego z podanych znaków: strcspn() size_t strcspn(const char *s1, const char *s2) liczbaniecyfrwliczbie = strcspn(napis, +-,. ); Funkcje przydatne do kontroli danych wejściowych 20

Operacje na łańcuchach I jeszcze problemy ze scanf() Poprawnie napisany kod powinien działać niezależnie od danych wejściowych Dwukrotnie wywołany scanf( %f,...) tak nie działa (przy błędnych danych): float a,b; printf("podaj dwe liczby rzeczywiste: "); scanf("%f", &a); // podaj 14,5 zamiast 14.5 scanf("%f", &b); //podaj dowolna liczbe printf("pobralem: %f i %f\n", a,b); scanf() jest bardzo uproszczoną funkcją, przeznaczoną tylko do: wczesnych etapów nauki programowania drobnych, własnych testów programisty Nie powinna występować w kodzie prawdziwej aplikacji 21

Operacje na łańcuchach Rozbicie łańcucha na elementy Rozwiązanie niektórych problemów ze scanf(): sscanf() sscanf() działa jak scanf(), ale pobiera dane nie z stdin, lecz z łańcucha podanego jako pierwszy argument: char przedsionek[10]; /*co najmniej rozmiar przewidywany na poprawne dane */ fgets(przedsionek, sizeof(przedsionek), stdin); // tu ew. przejrzenie/wyczyszczenie bufora sscanf(przedsionek, %f, &liczbarzeczywista); W ten sposób bufor wejściowy niezależnie od dopasowania do formatu pobieranej liczby zostanie skonsumowany zawsze warto go wyczyścić bo możliwe są też inne błędy Analogicznie można sscanf(przedsionek, %d, &liczbaint); 22

Operacje na łańcuchach Konwersje Zamiana łańcucha znaków napis zawierającego liczbę w postaci dziesiętnej na liczbę typu long int do zmiennej dlugiint (wymaga stdlib.h), np: dlugiint=strtol(napis, NULL, 10); Próba zamiany łańcucha znaków napis na liczbę typu float do zmiennej rzeczywista (wymaga stdlib.h), np: rzeczywista=strtof(napis, NULL); Próba zamiany łańcucha znaków napis na liczbę typu double do zmiennej podwojnarzeczywista (stdlib.h),np: podwojnarzeczywista=strtod(napis, NULL); 23

Operacje na łańcuchach Konwersje (c.d.) Zamiana liczby (inf, float) na łańcuch znaków: float liczbarzeczywista =12.5; int liczbacalkowita = -4; char napis[100]; sprintf(napis,"%f", liczbarzeczywista); //napis zawiera znaki: 12.5000 sprintf(napis,"%d", liczbacalkowita); //napis zawiera dwa znaki: -4 Połączenie liczby ze stałą tekstową: char napis[100]; int wiek; wiek = 5; sprintf(napis, "Mam %d lat", wiek); //napis zawiera: "Mam 5 lat" Połączenie liczy ze zmiennymi łańcuchowymi: char napis[100]; char marka[]="bmw"; float pojemnosc=5.5; char model[]="turbo"; 24 sprintf(napis, "%s %.1f %s", marka, pojemnosc, model); /*napis zawiera: "BMW 5.5 turbo" */

Co trzeba umieć? Rozumieć pojęcie wskaźnika do typu znakowego Manipulować łańcuchami Z użyciem wskaźników do typu znakowego Z użyciem podanych funkcji ze string.h Cięcie, Przeszukiwanie Konwersje Uwaga na ilość i kolejność parametrów funkcji 25