Znaki, tablice znakowe
W języku C do pamiętania znaków przeznaczony jest typ
char (charakter).
Zmienna typu char
zajmuje 1 bajt w pamięci. Ponadto każdemu znakowi odpowiada jego kod ASCII, który jest liczbą
całkowitą
(int).
Stałe znakowe zapisywane są między znakami pojedynczego cudzysłowia
(np.
‘a’, ‘A’
), natomiast do zapisu stałych tekstowych (ciągu znaków) używa się symboli: ” (np.
”stala tekstowa”).
Na końcu tekstu kompilator dodaje znak końca tekstu – jest to znak o
kodzie 0, który jest zapisywany
‘\0’.
Tekst, czyli ciąg znaków (string) zapisywany jest w pamięci
komputera w tablicy typu char.
Kod znaku a znak
Poniższy program wyświetla wprowadzone z klawiatury znaki i ich kody ASCI. Zastosowano funkcję
getchar
do wczytywania 1 znaku z klawiatury. Znak jest wyświetlany na ekranie za pomocą
specyfikacji
%c
stosowanej dla znaków oraz
%d.
Warunkiem stopu jest wprowadzenie spacji (‘ ‘) o
kodzie ASCII 32.
#include <stdio.h>
main()
{
int wybor;
do
{
wybor=getchar();
printf("%d %c\n",wybor,wybor);
}
while (wybor!=32); // do spacji
}
Używając powyższego programu można zauważyć, że kody małych i dużych liter różnią się o wartość
32, co odpowiada cyfrze 1 na 6 bicie od prawej strony (26=32).
Małe litery a duże litery
Kolejny program pokazuje kilka sposobów zamiany liter małych na duże i odwrotnie przy
zastosowaniu operatorów matematycznych ( -, + ) oraz bitowych operatorów logicznych ( |, & ):
#include <stdio.h>
#include <stdlib.h>
int main()
{
//zamiana malych liter na duze i z powrotem
unsigned i,j,maska;
i=97;
printf("i=%d i=%c\n",i,i);
i=i-32;
printf("i=%d i=%c\n",i,i);
// maska 0000000000100000
maska=32;
i=i | maska;
printf("i=%d i=%c\n",i,i);
maska=~maska;
//maska 1111111111011111
printf("maska=%d\n",maska);
i=i & maska;
printf("i=%d i=%c\n",i,i);
}
Przykład – zliczanie słów w tekście
Do ilustracji tablic tekstowych przedstawiony zostanie program, który wczytuje dowolny tekst i zlicza
występujące w nim słowa. Do zliczania słów zostaną wykorzystane dwie nieznacznie różniące się
funkcje. Kolejne słowo w tekście rozpoznawane jest po tym, że występuje przed nim przynajmniej
jedna spacja.
#include <stdio.h>
#include <stdlib.h>
#define MAX 150
int licz_slowa_2(text)
char *text;
{
char znak=' ',poprz;
int l=0;
while(poprz=znak,znak=*text++)
if(znak!=' ' && poprz==' ')l++;
return l;
}
int licz_slowa_1(text)
char *text;
{
char znak, poprz=' ';
int i=0,j=0;
while((znak=text[i++])!='\0')
{
if(znak!=' ' && poprz==' ')j++;
poprz=znak;
}
return j;
}
int main()
{
int slowa;
char tekst[MAX],*wtekst;
//wtekst=gets(tekst);
wtekst=fgets(tekst,20,stdin);
printf("%s\n",tekst);
printf("%s\n",wtekst);
slowa=licz_slowa_1(wtekst);
printf(" slow: %d\n slow: %d\n",slowa,licz_slowa_2(tekst));
}
Do wczytania tablicy tekstowej zastosowano funkcję
fgets.
Pierwszym aktualnym parametrem jest
nazwa tablicy, drugi parametr określa liczbę znaków do wczytania, a trzeci wskazuje plik, z którego
ma odbywać się czytanie - w tym przypadku jest to standardowe wejście, czyli klawiatura
(stdin).
Funkcja
fgets
zwraca wskaźnik do przeczytanego tekstu, czyli adres zerowego elementu tablicy.
Funkcja
fgets
dodatkowo dodaje na koniec tablicy znak końca linii (o kodzie 10), a po nim znak
końca tekstu
(\0).
Rozmiar zadeklarowanej tablicy powinien być zatem dłuższy od wczytywanego
tekstu o minimum dwa znaki. Alternatywnym rozwiązaniem jest zastosowanie funkcji
gets
(linia
zakomentarzowana w programie), jednak ze względu na bezpieczeństwo systemu funkcji tej nie
powinno się stosować. Na uwagę zasługuje konstrukcja:
znak=*text++
występującą w funkcji
licz_slowa_2.
Do zmiennej
znak
podstawiany jest jeden bajt spod adresu wskazywanego
przez zmienną
text,
a następnie zmienna ta jest inkrementowana, co oznacza, że będzie ona
wskazywać na kolejny bajt. W alternatywnej funkcji
licz_slowa_1
zastosowano konstrukcję:
znak=text[i++] -
do zmiennej
znak
podstawiany jest i-ty element tablicy
(text[i]),
a
następnie indeks i jest zwiększany o 1.