C-Programmierung: ctype.h
Übersicht
BearbeitenDer Header ctype.h enthält diverse Funktionen, mit denen sich einzelne Zeichen überprüfen lassen oder umgewandelt werden können. Die Funktionen liefern einen von 0 verschiedenen Wert, wenn c die Bedingung erfüllt, andernfalls liefern sie 0:
int isalnum(int c)
testet auf alphanumerisches Zeichen (a-z, A-Z, 0-9)int isalpha(int c)
testet auf Buchstabe (a-z, A-Z)int iscntrl(int c)
testet auf Steuerzeichen (\f, \n, \t ...)int isdigit(int c)
testet auf Dezimalziffer (0-9)int isgraph(int c)
testet auf druckbare Zeichen ohne Leerzeichenint islower(int c)
testet auf Kleinbuchstaben (a-z)int isprint(int c)
testet auf druckbare Zeichen mit Leerzeichenint ispunct(int c)
testet auf druckbare Interpunktionszeichenint isspace(int c)
testet auf Zwischenraumzeichen (engl. whitespace) (' ', '\f', '\n', '\r', '\t', '\v')int isupper(int c)
testet auf Grossbuchstaben (A-Z)int isxdigit(int c)
testet auf hexadezimale Ziffern (0-9, a-f, A-F)
Zusätzlich sind noch zwei Funktionen für die Umwandlung in Groß- bzw. Kleinbuchstaben definiert:
int tolower(int c)
wandelt Gross- in Kleinbuchstaben umint toupper(int c)
wandelt Klein- in Grossbuchstaben um
Häufig gemachte Fehler
BearbeitenWie Sie vielleicht sehen, erwarten die Funktionen aus <ctype.h>
als Parameter einen int, obwohl es eigentlich ein char sein sollte. Immerhin arbeiten die Funktionen ja mit Zeichen.
Die Ursache hierfür liegt im C-Standard selbst. Laut C-Standard muss c entweder »als unsigned char repräsentierbar oder der Wert des Makros EOF sein«. Ansonsten ist das Verhalten undefiniert. EOF ist im Standard als negativer int-Wert definiert, unsigned char kann aber niemals negative Werte annehmen. Um dem Standard zu genügen, muss also ein ausreichender Parametertyp deklariert werden, der sowohl den unsigned char-Wertebereich wie auch negative int-Werte abbilden kann. Dies kann der Basisdatentyp int.
Das alleine ist noch nicht schlimm. Aber: in C gibt es drei verschiedene Arten von char-Datentypen: char, signed char und unsigned char. In einer Umgebung mit Zweierkomplementdarstellung, in der ein char 8 Bit groß ist (ja, es gibt auch größere), geht der implementierungsabhängige Wertebereich von signed char meistens von -128 bis +127, der von unsigned char von 0 bis meistens 255. Wenn man jetzt noch annimmt, dass der Zeichensatz ISO-8859-1 (latin1) oder Unicode/UTF-8 ist, darf man diesen Funktionen keine Strings übergeben, die möglicherweise Umlaute enthalten. Ein typisches Beispiel, bei dem das dennoch geschieht, ist:
int all_spaces(const char *s) { while (*s != '\0') { if (isspace(*s)) /* FEHLER */ return 0; s++; } return 1; }
Der Aufruf von all_spaces("Hallöle") führt dann zu undefiniertem Verhalten. Um das zu vermeiden, muss man das Argument der Funktion isspace in einen unsigned char umwandeln. Das geht zum Beispiel so:
if (isspace((unsigned char) *s))