Wczytywanie i drukowanie tablic znakowych cz.4 Długość
Transkrypt
Wczytywanie i drukowanie tablic znakowych cz.4 Długość
Katedra Elektrotechniki Teoretycznej i Informatyki wykład 9 - sem.III Dr inż. M. Czyżak Język ANSI C – tablice znaków Tablice znaków (łańcuchy) Tablice znaków stanowią specjalny rodzaj tablic o budowie ułatwiającej przetwarzanie tekstów. Przetwarzanie obejmuje szereg operacji takich jak tworzenie, modyfikację i przeszukiwanie. Tablice znakowe mogą być definiowane w sposób następujący: char s1[5]; char s2[5]="ABCD"; char s3[ ]="abcd"; Definicje tablic s2 i s3 zawierają też inicjalizację. Tablice znaków zakończone są znakiem ‘\0’. Znak ten umożliwia wykrycie końca tablicy, a tym samym umożliwia traktowanie tablic znaków w nieco inny sposób niż zwykłych tablic. Język ANSI C – łańcuchy Budowa tablicy znaków Przykładowo, tablica s2 ma następującą budowę: 'A' 'B' 'C' 'D' '\0' Tak więc definiując tablicę znakową należy przewidzieć jedną komórkę na znak końcowy ‘\0’. Język ANSI C – łańcuchy Stałe łańcuchowe i wskaźniki do znaków cz. 1 Stałe łańcuchowe ( stałe typu tablica znaków), np. "Tekst" , są przechowywane w pamięci jako tablice znaków z ostatnim elementem równym ‘\0’. Stała "Tekst" jest typu char *, czyli wskaźnik do znaku. Wskaźnik do znaku może więc zostać zainicjowany stałą łańcuchową char *ps="Tekst"; // sposób 1 Inicjalizacja taka jest równoważna parze instrukcji char *ps;// sposób 2 ps="Tekst"; W przypadku sposobu 1 do wskaźnika ps jest przypisywany wskaźnik do tablicy znaków, a nie do *ps ( czyli nie do miejsca wskazywanego przez ps). Język ANSI C – łańcuchy Stałe łańcuchowe i wskaźniki do znaków cz. 2 Warto też zauważyć, że przy definicji tablicy znakowej char s2[5]; nie jest możliwa realizacja przypisania w programie s2="ABCD" ;// przypisanie błędne Wynika to z faktu, że s2 jako nazwa tablicy jest typu stały wskaźnik do znaku, który to wskaźnik nie może być zmieniony poprzez przypisanie. Język ANSI C – łańcuchy Wczytywanie i drukowanie tablic znakowych cz.1 W języku C istnieje specjalny deskryptor formatu %s umożliwiający wczytywanie i drukowanie tablic znakowych przy użyciu funkcji scanf i printf, istnieją też inne funkcje biblioteczne realizujące te operacje. Jeśli zdefiniowano tablicę znakową char s1[5]; można ją wczytać i wydrukować w poniższy sposób: printf("\n Podaj lancuch :"); scanf("%s",s1); // nie stosuje się znaku & przed // s1, gdyż s1 jest wskaźnikiem. printf("\n Wczytany lancuch to :%s ", s1); Język ANSI C – łańcuchy Wczytywanie i drukowanie tablic znakowych cz.2 Jednak wczytywanie łańcuchów przy użyciu funkcji scanf nie pozwala na wczytanie łańcuchów zawierających spacje, gdyż wczytywanie łańcucha jest przerywane po napotkaniu spacji. Dla takich łańcuchów należy zastosować funkcję gets lub też funkcję fgets. Funkcja gets ma następujący prototyp: char* gets(char *s); Język ANSI C – łańcuchy Wczytywanie i drukowanie tablic znakowych cz.3 Opis działania funkcji gets: Funkcja wczytuje znaki ze standardowego wejścia ( stdin) aż do momentu napotkania znaku nowej linii (Enter). Wczytywane znaki są wyświetlane na ekranie i zapamiętywane począwszy od miejsca wskazywanego przez argument funkcji, s. Znak nowej linii jest zastępowany w łańcuchu znakiem końca łańcucha '\0'. Ciąg wejściowy może zawierać pewne białe znaki (np. spacje lub znaki tabulacji poziomej). Funkcja zwraca s, gdy operacja się powiodła lub NULL w przypadku wystąpienia błędu. Język ANSI C – łańcuchy Wczytywanie i drukowanie tablic znakowych cz.4 Długość wczytywanego ciągu znaków nie jest ograniczana, co przy ciągach dłuższych niż to wynika z argumentu funkcji gets, może powodować uszkodzenie sąsiednich obszarów pamięci. Przykład. char lan [20]; printf ("\n Podaj lancuch:"); gets(lan); Bardziej uniwersalną funkcją służącą do wczytywania łańcuchów jest fgets. . Język ANSI C – łańcuchy Wczytywanie i drukowanie tablic znakowych cz.5 Funkcja fgets ma nastepujący prototyp: char *fgets(char *s, int n, FILE *stream); Funkcja ta czyta do łańcucha s znaki ze strumienia wejściowego (pliku) określonego przez wskaźnik stream. Funkcja kończy wczytywanie znaków po przeczytaniu n - 1 znaków lub też po pojawieniu się znaku nowej linii i wpisuje znak nowej linii do do łańcucha. Zwraca łańcuch lub NULL w przypadku pojawienia się końca pliku lub błędu. Przykład. Wczytywanie ze standardowego strumienia wejściowego. char lan [20]; printf ("\n Podaj lancuch:"); fgets(lan,15,stdin); Język ANSI C – łańcuchy Wczytywanie drukowanie tablic znakowych cz.6 Do drukowania tablic znakowych poza funkcją printf można zastosować funkcje puts i fputs. Prototyp funkcji puts ma postać int puts (const char *s); Funkcja wyprowadza łańcuch na wyjście standardowe (stdout) i dołącza znak nowej linii. W przypadku pomyślnej realizacji funkcja zwraca wartość nieujemną, w przeciwnym przypadku EOF. int fputs(const char *s, FILE *stream); Funkcja zapisuje łańcuch s do do strumienia wyjściowego określonego przez wskaźnik stream. Funkcja nie zapisuje do pliku znaku '\0'. W przypadku powodzenia operacji funkcja zwraca wartość nieujemną, w przypadku błędu wartość EOF. Język ANSI C – łańcuchy Przykład. Zastosowanie funkcji fputs do wydruku w standardowym strumieniu wyjściowym (stdout). #include <stdio.h> #include <string.h> int main(int argc, char **argv) { char s1[10]="ABCDE"; char s2[10]="abcde"; fputs(s1,stdout); fputc('\n',stdout);// dodanie znaku nowej linii fputs(s2,stdout); fputc('\n',stdout);// wyprowadzenie znaku nowej linii system ("pause"); } Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 1 Poniżej omówione zostaną wybrane najczęściej spotykane funkcje związane z przetwarzaniem łańcuchów (pełny zestaw w <string.h> i <stdlib.h>, opisano je też w materiale TabliceZnakowe.pdf. Funkcje te to: strlen , strcpy, strcat, strcmp, strlwr, strupr, atoi, itoa, strchr, strstr. Funkcja strlen size_t strlen(const char *s); Funkcja oblicza długość łańcucha s bez końcowego znaku '\0'. Przykład. Zastosowanie funkcji strlen do wyznaczania długości łańcucha. char s[10]="12345678"; int dl; dl=strlen(s);// dl będzie równe 8 Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 2 Funkcja strcpy char *strcpy(char *dest, const char *src); Kopiuje łańcuch src do łańcucha dest. Kopiowanie ulega zakończeniu po skopiowaniu znaku '\0' kończącego łańcuch src. Funkcja zwraca wskaźnik dest . Przykład. #include <stdio.h> #include <string.h> int main(void) { char lan1[10="ABC"; char lan2[ ]= "12345"; strcpy(lan1, lan2);// kopiowanie łańcuchów printf("%s", lan1); return 0; } Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 3 Funkcja strcat char *strcat(char *dest, const char *src); Dołącza łańcuch src do końca łańcucha dest. Funkcja zwraca wskaźnik dest. Długość połączonego łańcucha jest równa strlen(dest)+strlen(src). Przykład. #include <stdio.h> #include <string.h> int main(void) { char lan1[20]="abcde"; char lan2[ ]= "123456789"; strcat(lan1, lan2); printf("%s", lan1); return 0; } Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 4 Funkcja strcmp int strcmp(const char *s1, const char *s2); Porównuje łańcuch s1 z łańcuchem s2, porównując kody znaków (np. kody ASCII) obu łańcuchów. Porównanie kończy się, gdy w jednym z łańcuchów zostanie napotkany znak o większym kodzie lub też zostanie osiągnięty koniec jednego z łańcuchów ( wtedy dłuższy łańcuch uważany jest za większy). Funkcja zwraca - wartość <0, gdy s1<s2, -wartość 0, gdy s1==s2, -wartość >0, gdy s1>s2. Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 5 Przykład. Zastosowanie funkcji strcmp. #include <stdio.h> #include <string.h> int main(void) { char lan1[10]="abcde",lan2[10 ]; int p; printf(" Podaj lancuch:"); scanf("%s", lan2); p= strcmp(lan1,lan2); if (p<0) printf(" lan1<lan2"); else printf("\n lan1=lan2"); else printf("\n lan1>lan2"); getchar(); return 0; } if ( p==0) Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 6 Funkcja strlwr char *strlwr(const char *s); Zamienia w łańcuchu duże litery na małe, innych znaków nie zmienia. Łańcuch lan1 ma postać char lan1[ ]="String ABC"; strlwr(lan1); Po wykonaniu instrukcji, lan1 ulega zmianie na łańcuch "string abc". Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 7 Funkcja strlupr char *strupr(char *s); Zamienia w łańcuchu małe litery na duże, innych znaków nie zmienia. Łańcuch lan2 ma postać char lan2[ ]="lancuch abc"; strupr(lan2); Po wykonaniu instrukcji, lan2 ulega zmianie na łańcuch "LANCUCH ABC" . Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 8 Funkcja atoi int atoi(const char *s); Funkcja atoi zamienia lańcuch będący argumentem funkcji na liczbę całkowitą, rozpoznaje ona (w zadanym porządku) - opcjonalny łąńcuch znaków tabulacji i spacji - opcjonalny znak - łąńcuch cyfr Łańcuch musi mieć następującą postać: [ws] [sn] [ddd] // ws - białe znaki,sn - znak liczby Pierwszy nierozpoznany znak kończy konwersję. Nadmiar nie jest rozpoznawany ( wynik jest wtedy nieokreślony). Wartość zwracana atoi zwraca liczbę całkowitą odpowiadającą łańcuchowi wejściowemu. Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 9 Funkcja itoa char *itoa(int value, char *string, int radix); Funkcja zamienia liczbę będącą pierwszym argumentem funkcji ( value) na łańcuch znaków umieszczany w tablicy znakowej (string) będącej drugim argumentem. Konwersja odbywa się dla podstawy systemu liczbowego podanej jako trzeci argument funkcji (radix). Podstawa systemu musi należeć do przedziału [2,36]. Jeśli liczba jest ujemna i podstawa systemu jest równa 10, pierwszym znakiem łańcucha znaków jest znak '-'. Język ANSI C – łańcuchy Standardowe funkcje łańcuchowe cz. 10 Funkcja strchr char *strchr(const char *s, int c); Funkcja wyszukuje w łańcuchu znaków s znak c. Funkcja zwraca wskaźnik do pierwszego wystąpienia znaku c. Jeśli znaku nie ma, funkcja zwraca zerowy wskaźnik null. Funkcja strstr char *strstr(const char *s1,const char *s2 ); Funkcja wyszukuje w łańcuchu znaków s1 łańcuch s2. Funkcja zwraca wskaźnik do pierwszego wystąpienia łańcucha s2 (do pierszego znaku łańcucha s2). Jeśli łańcucha s2 nie ma, funkcja zwraca zerowy wskaźnik null. Język ANSI C – łańcuchy Przykład. Wczytywanie dwuwymiarowej tablicy znaków (tablicy łańcuchów) oraz sortowanie niemalejąco. (cz.1) // cz. 1 programu #include <stdio.h> #include <conio.h> #include <string.h> int main(int argc, char* argv[]) { char stab[5][10]; char spom[10]; int i,zam; for(i=0;i<5;i++) { printf("\n lan%d :",i); scanf("%s",stab[i]); // wczytywanie tablicy znaków // będącej wierszem tablicy dwuwymiarowej } for(i=0;i<5;i++) printf("\n lan %s",stab[i]); Język ANSI C – łańcuchy Cz. 2 programu do { zam=0; for (i=0;i<4;i++) if (strcmp(stab[i],stab[i+1])>0) { strcpy(spom, stab[i]); strcpy(stab[i], stab[i+1]); strcpy( stab[i+1],spom ); zam=1; } } while (zam); printf("\n\n Tablica po sortowaniu"); for(i=0;i<5;i++) printf("\n lan %s",stab[i]); getch(); return 0;}