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 **łańcuch znakowy** to tablica zawierająca ciąg znaków zakończony wartością 0 (znak '' '\0' '') \\ {{zajecia:pp1_2021_1:string.png?600|}} * 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. Wykorzystaj funkcje ''czytaj_linię()'' do napisania programu, który ponumeruje linie wczytane ze standardowego wejścia. Tekst wejściowy czytany jest linia po linii aż do końca strumienia (do wystąpienia ''EOF'''). **Przykład:** 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 2: dolor sit amet, 3: 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> ===== Ćwiczenie: unikatowe linie ===== Napisz program, który usuwa powtarzające się po sobie linie tekstu. Program czyta tekst ze standardowego wejścia aż do napotkania końca pliku (''EOF'') i wypisuje kolejne linie, z pominięciem tych, które się powtarzają. Do realizacji ćwiczenia wykorzystaj funkcje z biblioteki ''string.h''. Przykładowo, jeżeli na wejściu programu podamy następującą treść: <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ą (uogólnionego) szyfru Cezara. W tym celu zadeklaruj w programie funkcję o nazwie ''szyfr()'', która szyfruje tekst zawarty w tablicy znakowej zamieniając kolejne znaki alfabetu angielskiego na znaki stojące o ''n'' pozycji dalej w alfabecie. Przykładowo dla ''n=3'' litera ''a'' zamieniana jest na ''d'', litera ''b'' na ''e'', z kolei litera ''x'' zamieniana jest na ''a'', ''y'' na ''b'', ''z'' na ''c''. Zamianie ulegają wyłącznie znaki alfabetu angielskiego (małe litery ''a-z'' i duże ''A-Z''). Pozostałe znaki znajdujące się w napisie pozostają niezmienione. **Argumenty funkcji.** Funkcja ''szyfr()'' ma 2 argumenty: * tablica znakowa ''t'' zawierająca napis do zaszyfrowania * liczba całkowita ''n'' określająca o ile pozycji w alfabecie przesuwamy litery **Wartość zwracana funkcji:** adres tablicy ''t'' zawierającej zaszyfrowany napis w którym litery zostały zamienione na litery położone o ''n'' pozycji dalej w alfabecie. Wykorzystaj funkcję ''szyfr()'' do napisania programu służącego do szyfrowania tekstu za pomocą szyfru Cezara. Program na początku działania pobiera liczbę całkowitą ''n'' a następnie czyta kolejne linie tekstu aż do końca strumienia (''EOF''). Każda kolejna linia tekstu jest szyfrowana za pomocą funkcji ''szyfr()'' zgodnie z podaną wcześniej wartością przesunięcia ''n'' a wynik jest wypisywany na standardowym wyjściu. Zakładamy, że tekst nie będzie zawierał linii dłuższych niż 1000 znaków. **Przykłady działania.** \\ Dla danych wejściowych: <code> 3 Ala ma kota </code> na ekranie pojawi się Dkd pd nsxd Gdy podamy ujemną wartość ''n'' to możemy odszyfrować wcześniej zakodowaną wiadomość. <code> -3 Dkd pd nsxd Ala ma kota </code> Inny przykład: <code> 5 Ala ma kota Fqf rf ptyf a Ewa ma psa f Jcf rf uxf </code>