6 STRUKTURY
/* getword: weź następne słowo lub znak z wejścia */ int getword(char *word, int lim)
{
int c, getch(void); void ungetch(int); char *w = word;
while (isspace(c = getch()))
i
if (c != EOF)
*w-h- = c; if (! isalpha(c)) {
*w = ’\0’; return c;
for (; —lim > 0; w++)
if (! isalnum(*w = getch())) { ungetch(*w); break;
*w = ’\0’; return word[0];
Funkcja getword korzysta z funkcji getch i ungetch, które napisaliśmy w rozdz. 4. Kompletując znaki alfanumeryczne, getword czyta o jeden znak za dużo. Wywołanie funkcji ungetch oddaje ten znak z powrotem na wejście, umożliwiając wczytanie go przy ponownym wywołaniu. Funkcja getword korzysta z następujących makr zdefiniowanych w standardowym nagłówku <ctype.h>: isspace do pomijania białych znaków, isalpha do rozstrzygnięcia, czy dany znak jest literą, oraz isalnum do zidentyfikowania liter i cyfr.
A
Ćwiczenie 6.1. Nasza wersja funkcji getword nie obsługuje poprawnie znaków podkreślenia, stałych napisowych, komentarzy oraz instrukcji preprocesora. Napisz lepszą wersję tej funkcji. -
Aby zilustrować niektóre z rozważań związanych ze wskaźnikami do struktur i tablicami struktur, napiszemy jeszcze raz program zliczający słowa kluczowe języka C tym razem używając wskaźników zamiast indeksów tablic.
6.4 WSKAŹNIKI DO STRUKTUR
Zewnętrznej deklaracji tablicy keytab nie trzeba zmieniać, modyfikacji tomiast funkcje main i binsearch.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXWORD 100
int getword(char *, int);
struct key *binsearch(char *, struct key *, int);
I* zlicz słowa kluczowe C; wersja wskaźnikowa */ main()
char word[MAXWORD]; struct key *p;
while (getword(word, MAXWORD) != EOF) if (isalpha(word[0]))
if ((p = binsearch(word, keytab, NKEYS)) != NULL) p->count++;
for (p = keytab; p < keytab + NKEYS; p-H-) if (p->count > 0)
printf(”%4d %s”, p->count, p->word); return 0;
I* binsearch: szukaj słowa w tab[0]...tab[n-1] */ struct key *binsearch(char *word, struct key *tab, int n)
int cond;
struct key *low = &tab[0]; struct key *high = &tab[n]; struct key *mid;
while (Iow < high) {
mid = Iow + (high-low) / 2; if ((cond = strcmp(word, mid->word)) < 0) high = mid; else if (cond > 0)
Iow = mid + 1; else
return mid;
return NULL;
}
185