poprzedni temat | w górę | następny temat

Napisy

Typ char

Do przechowywania pojedynczych znaków służy typ char. Zmienna tego typu zajmuje zawsze 1 B.

char znak1 = 'A';
char znak2 = 65;
if(znak1 == znak2){
  printf("Znak 'A' to liczba 65.\n");
}
printf("Kod ASCII cyfry 0 to %d.\n", '0');

Wczytywanie i wypisywanie wartości typu char

Specyfikator wejścia-wyjścia dla typu char to %c. Uwaga: nie są pomijane białe znaki (spacja, tabulacja, przejście do nowej linii itp.).

char odpowiedz;
printf("Czy ten program jest poprawny? [T/N] ");
scanf("%c", &odpowiedz);
if( odpowiedz == 'T' ){
  // ...
} else {
  // ...
}

Operacje na cyfrach i literach

Kod znaku cyfry 0 to '0' czyli liczba 48. Aby skonwertować znak cyfry do odpowiadającej jej liczby, wystarczy odjąć od niej znak cyfry '0'. Aby skonwertować liczbę na znak cyfry (oczywiście liczbę jednocyfrową), należy do niej dodać cyfrę '0'.

char cyfra = '3';
int liczba = cyfra - '0';
liczba *= 2;
cyfra = liczba + '0';
printf("%c", cyfra);

Małe (i oddzielnie wielkie) litery alfabetu angielskiego są umieszczone w tabeli kodów ASCII jedna za drugą bez przerw. Aby z litery 'a' otrzymać 'b', wystarczy napisać 'a'+1.

Przesunięcie między małymi a wielkimi literami, które sobie odpowiadają, jest stałe — 'A'-'a', 'B'-'b', ..., 'Z'-'z' to ta sama liczba. Dlatego, mając zmienną znak, która spełnia warunek 'a' <= znak && znak <= 'z' (czyli jest małą literą), jeśli chcemy otrzymać odpowiadającą jej wielką literę, wystarczy, że napiszemy znak+'A'-'a'.

Tablice znaków

Do przechowywania napisów w pamięci służą tablice znaków:

char napis[30];

Za ostatnim znakiem napisu musi wystąpić wartość '\0' (czyli liczba 0), która jest znacznikiem końca napisu. Oczywiście rozmiar tablicy znaków przeznaczonej na przechowanie napisu nie może być mniejszy od rzeczywistej długości napisu powiększonej o 1. Programista musi się samodzielnie postarać o spełnienie tego warunku w każdym miejscu w kodzie programu. Z tego powodu posługiwanie się napisami w języku C jest niewygodne (w porównaniu z nowszymi językami), początkowo trudne i może przyczyniać się do powstawania częstych błędów.

Znacznikiem końca napisu jest znak '\0', więc najczęściej nie ma potrzeby znać rzeczywistego rozmiaru tablicy, w której napis jest zapisany — o ile się w niej mieści. Z tego powodu funkcja, której przekazywany jest napis, nie musi dostawać jego długości podanego jawnie za pomocą dodatkowego parametru.

Iterowanie po znakach napisu

Często popełnianym błędem, gdy chcemy przejść po wszystkich znakach napisu, jest stosowanie warunku jak w pętli poniżej:

for(i=0; i < strlen(napis); ++i){
  // zrob_cos_z(napis[i]);
}

Tak postawiony warunek spowoduje, że długość napisu będzie musiała być obliczona za każdym razem, gdy ma być obliczony warunek. W tym miejscu lepiej jest wykorzystać własność napisów dotyczącą sposobu zaznaczania ich końca — znak '\0' stoi zawsze na końcu napisu.

for(i=0; napis[i] != '\0'; ++i){
  // zrob_cos_z(napis[i]);
}

Inicjowanie napisów

char napis1[] = {'A', 'l', 'a', ' ', 'm', 'a', ' ', 'k', 'o', 't', 'a', '\0'};
char napis2[] = "Ala ma kota";
char *napis3  = "Ala ma kota";

Jaka jest różnica między napis2napis3? napis3 to wskaźnik do stałego napisu, czyli takiego, którego zawartości nie można modyfikować.

Wczytywanie i wypisywanie napisów

Do wczytywania napisu ze standardowego wejścia używamy funkcji fgets, która przyjmuje jako parametry: napis, jego maksymalny rozmiar oraz plik, z którego ma odbywać się wczytywanie (standardowe wejście to stdin).

char napis[100];
fgets( napis, 100, stdin);

Funkcja fgets wczytuje napis o długości maksymalnie o jeden mniej, niż podany rozmiar tablicy. Jeśli wcześniej wystąpi koniec pliku lub znak przejścia do nowej linii, również w tym momencie kończy się czytanie, przy czym znak przejścia do nowej linii jest zapisywany w tablicy. Zachowana jest konwencja zakończenia napisu znakiem '\0'.

Nie należy używać funkcji scanf do wczytywania napisów, ponieważ może to powodować błąd wyjścia poza zakres tablicy. Nie jesteśmy w stanie w żaden sposób temu zapobiec, gdy używamy scanf a użytkownik wpisze napis o większym rozmiarze niż rozmiar tablicy, którą przekazaliśmy do funkcji.

Do wypisywania można używać funkcji printf, przy czym należy podać napis jako drugi lub dalszy argument:

printf("%s", napis); // dobrze
printf(napis); // źle!

Można również zastosować funkcję puts:

puts(napis);

Zadania

  1. Napisz funkcję, która przyjmuje jako parametr napis i zwraca jego długość.

  2. Napisz funkcję, która przyjmuje jako parametr napis oraz tablicę znaków o rozmiarze co najmniej takim jak napis. Funkcja ma umieścić w drugiej tablicy odwrócony (pierwszy) napis.

  3. Napisz funkcję, która przyjmuje jako parametr napis i zwraca 1, jeśli napis jest palindromem; 0 w przeciwnym razie.

  4. Napisz funkcję, która przyjmuje jako parametry dwa napisy i zwraca 1, jeśli są sobie równe; 0 w przeciwnym razie.

  5. Napisz funkcję, która przyjmuje jako parametr napis i zwraca liczbę słów w nim zapisanych. Przyjmujemy, że słowa są rozdzielone pojedynczymi znakami spacji.

  6. Napisz funkcję, która przyjmuje jako parametr napis oraz tablicę znaków o rozmiarze co najmniej takim jak napis. Funkcja ma skopiować pierwszy napis do drugiej tablicy.

  7. Napisz funkcję, która przyjmuje jako parametr napis i zamienia w nim wszystkie wielkie litery na małe.

  8. Napisz funkcję, która przyjmuje jako parametr napis i zmienia go tak, że co druga litera jest wielka a wszystkie pozostałe są małe. Na przykład napis "Jakie to dziwne zadanie..." zamienia na "jAkIe tO DzIwNe zAdAnIe...".

  9. Napisz funkcję otrzymującą jako parametry trzy tablice znaków i zapisującą do trzeciej tablicy konkatenację napisów znajdujących się w dwóch pierwszych tablicach (czyli dla napisów "Ala m""a kota" znajdujących się w pierwszych dwóch argumentach do trzeciej tablicy powinien zostać zapisany napis "Ala ma kota").

  10. Napisz funkcję, która otrzymuje jako parametry dwa napisy i dopisuje drugi napis na koniec pierwszego.

  11. Napisz funkcję, która w napisie podanym jako parametr usunie wielokrotne wystąpienia spacji obok siebie. Na przykład napis " Ala ma kota. " przekształci w napis " Ala ma kota. ".

poprzedni temat | w górę | następny temat