Edytuj stronę Odnośniki Fold/unfold all ODT export Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić. ====== Łańcuchy znaków (stringi) ===== * **napis** lub **łancuch znakowy** to tablica zawierająca ciąg znaków zakończony wartością 0 (znak '' '\0' '') * dowolny ciąg znaków w cudzysłowach jest stałym napisem, np.: napis ''"Ala ma kota"'' * funkcja ''printf()'' posiada specyfikator formatu ''%s'' służący do wyświetlania zmiennych napisowych **Przykład 1:**\\ Poniższy program oblicza ilość znaków w napisie "Ala ma kota". <file C str2.c> #include <stdio.h> int main() { char napis[] = "Ala ma kota"; int i = 0; while(napis[i] != '\0') { i++; } printf("Napis \"%s\" zawiera %d liter\n", napis, i); return 0; } </file> Po uruchomieniu programu na ekranie pojawi się: <code> Napis "Ala ma kota" zawiera 11 liter </code> **Przykład 2:**\\ Poniższy program wypisuje napis "Ala ma kota" w kolejnych liniach. W każdej kolejnej linii wypisywany komunikat jest skracany o jeden, początkowy znak. <file C str3.c> #include <stdio.h> int main() { char *napis = "Ala ma kota\n"; while(*napis != '\0') { printf(napis); napis++; } return 0; } </file> Po uruchomieniu programu na ekranie pojawi się: <code> Ala ma kota la ma kota a ma kota ma kota ma kota a kota kota kota ota ta a </code> ==== Ćwiczenie - Czytaj linię === W języku C mamy do dyspozycji funkcję ''gets()'', która czyta linię tekstu ze standardowego wejścia (zobacz [[https://pl.wikibooks.org/wiki/C/gets|gets()]]). Jednak użycie tej funkcji jest niebezpieczne, gdyż nie jest zabezpieczona przed przepełnieniem bufora, tzn. taką sytuacją , gdy linia testu jest dłuższa niż ilość miejsca w tablicy do której wczytujemy znaki. Napiszmy własną wersję funkcji ''gets()'', która będzie pozbawiona tej wady. **Opis funkcji**\\ Funkcja o nazwie ''czytaj_linie()'' czyta linię tekstu ze standardowego wejścia ale nie więcej niż ''n'' znaków. Kolejne znaki odczytane z wejścia umieszczane są w tablicy znakowej wskazywanej przez ''str'' tworząc napis (łańcuch znakowy), tzn. za ostatnim znakiem umieszczane jest zero (znak '''\0'''). Znak nowego wiersza '''\n''' nie jest umieszczany w tablicy ''str''. Jeżeli napotkany zostanie koniec pliku (EOF) funkcja kończy swoje działanie zwracając wartość ''NULL''.' Do wczytywania kolejnych znaków ze standardowego wejścia użyj funkcji ''[[http://pl.wikibooks.org/wiki/C/getchar|getchar()]]''. **Argumenty funkcji:** tablica znakowa ''str'' oraz liczba całkowita ''n'' określająca maksymalną liczbę znaków jaka może zostać wczytana do tablicy ''str''\\ **Wartość zwracana:** funkcja zwraca adres tablicy ''str'' w przypadku sukcesu lub NULL w przypadku natrafienia na koniec pliku. Niżej znajduje się fragment kodu zawierający definicje funkcji ''czytaj_linie()'' oraz krótki program, który numeruje wszystkie linie ze standardowego wejścia. <file C czytaj_linie.c> #include <stdio.h> char *czytaj_linie(char *str, int n) { int i=0, znak; while( i < n-1 && (znak = getchar()) != '\n' && znak != EOF) { str[i] = znak; i = i + 1; } str[i]='\0'; if (znak == EOF) return NULL; return str; } #define MAXLINE 100 int main() { int i = 1; char napis[MAXLINE]; while(czytaj_linie(napis, MAXLINE)) { printf("%d: %s\n", i, napis); i = i + 1; } return 0; } </file> Jeżeli na standardowym wejściu powyższego programu podamy tekst <code> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </code> wówczas na ekranie powinien pojawić się taki tekst: <code> 1: Lorem ipsum dolor sit amet, 2: consectetur adipiscing elit. </code> ==== Biblioteka string.h ==== W bibliotece standardowej znajduje się szereg funkcji związanych z operacjami na łańcuchach znakowych. Zadeklarowane są one w pliku [[http://www.cplusplus.com/reference/cstring/|string.h]]. Oto lista kilku wybranych funkcji: * [[https://pl.wikibooks.org/wiki/C/strlen|strlen]] - wyznacza długość napisu \\ <code C>int strlen(char *napis)</code> * [[https://pl.wikibooks.org/wiki/C/strcpy|strcpy]] - kopiowanie napisu z ''src'' do ''dest'' \\ <code C>char* strcpy(char *src, char* dest)</code> * [[https://pl.wikibooks.org/wiki/C/strcmp|strcmp]] - porównywanie napisów w porządku alfabetycznym \\ <code C>int strcmp(char *napis1, char* napis2)</code> * [[https://pl.wikibooks.org/wiki/C/strcat|strcat]] - łączenie napisów, dodaje ''src'' na końcu ''dest'' \\ <code C>char* strcat(char *src, char* dest)</code> * [[https://pl.wikibooks.org/wiki/C/strstr|strstr]] - znajduje ''wzor'' w napisie \\ <code C>char* strstr(char *napis, char* wzor)</code> **Przykład** Poniżej znajduje się program, który demonstruje użycie funkcji ''strcpy'' oraz ''strcmp''' z biblioteki ''string.h''. Program czyta tekst ze standardowego wejścia aż do napotkania końca pliku i wypisuje kolejne linie, z pominięciem tych, które się powtarzają. \\ Uwaga: program używa funkcji ''czytaj_linie()'', której definicja znajduje się w poprzednim przykłądzie. <file C polacz_linie.c> #include <string.h> #define MAXLINE 1000 int main() { char linia[MAXLINE]; char linia_poprzednia[MAXLINE]; linia_poprzednia[0] = '\0'; while(czytaj_linie(linia, MAXLINE) != NULL) { if (strcmp(linia, linia_poprzednia) != 0) { printf("%s\n", linia); strcpy(linia_poprzednia, linia); } } return 0; } </file> Przykładowo, jeżeli na wejście programu przekierujemy plik zawierający: <code> Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, consectetur adipiscing elit. consectetur adipiscing elit. </code> na wyjściu otrzymamy unikatowe linie <code> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </code> ==== Zadnie - Szyfr cezara ==== Napisz program, który szyfruje tekst za pomocą szyfru Cezara. W tym celu zadeklaruj w programie funkcję o nazwie ''szyfr()'', która w danej tablicy znakowej zawierającej napis zamieni wszystkie znaki alfabetu na znaki stojące o 3 pozycje dalej w alfabecie, tzn. ''a'' zamieniane jest na ''d'', litera ''b'' na ''e'', itd. Litera ''z'' zamieniana jest na ''a'', ''y'' na ''b'', ''z'' na ''c''. Zamianie ulegają wyłącznie znaki alfabetu (małe ''a-z'' i duże ''A-Z''). **Argumenty funkcji:** tablica znakowa ''t'' zawierająca napis do zaszyfrowania \\ **Wartość zwracana:** adres tablicy 't' zawierającej zaszyfrowany tekst \\ Napisz program, który przeczyta linię tekstu se standardowego wejścia, zaszyfruje tekst za pomocą funkcji ''szyfr()'' a następnie wypisze wynik na ekranie. Zakładamy, że linie tekstu nie będą dłuższe niż 1000 znaków. Przykładowo dla podanego tekstu: Ala ma kota na ekranie pojawi się Dkd pd nsxd **Dla chętnych** * rozszerz funkcję ''szyfr()'' o możliwość zamiany znaków w tekście na znaki przesunięte o dowolną liczbę całkowitą w alfabecie. Wartość ta stanowi kolejny argument funkcji. Znaki w alfabecie zamieniane są cyklicznie. Podanie wartości ujemnej odpowiada przesunięciu znaków w przeciwną stronę w alfabecie i w efekcie deszyfrację wiadomości zakodowanej taka samą wartością dodatnią. * niech program działa nieprzerwanie dla dowolnej liczby wprowadzonych linii aż do pojawienia się pustej linii. Każda kolejna linia wczytana na wejściu jest wypisywana w zaszyfrowanej postaci. ==== Zadanie - Odwracanie napisów ===== Napisz program, który odwraca kolejność znaków w liniach tekstu. W tym celu zdefiniuj funkcję o nazwie ''odrwracanie()'', która w podanej tablicy znakowej odwróci kolejność wszystkich znaków w łańcuchu znakowym. **Argumenty funkcji:** napis (tablica znakowa). Po wykonaniu funkcji znaki w napisie będą umieszczone w odwrotnej kolejności \\ **Wartość zwracana:** adres tablicy z odwróconym napisem\\ Napisz program, który czyta linie tekstu ze standardowego wejścia aż do napotkania końca pliku. Każda linia wypisywana na ekranie z odwróconą kolejnością znaków. Zakładamy, że linie tekstu nie będą dłuższe niż 1000 znaków. Do wczytywania linii tekstu możesz wykorzystać funkcję ''czytaj_linię()'' zdefiniowaną wyżej. Przykład działania programu:\\ <code> Ala ma kota atok ma alA a Ewa ma psa asp am awE a </code>