Zum Inhalt springen

C-Programmierung: ctype.h

Aus Wikibooks

Übersicht

[Bearbeiten]

Der 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 Leerzeichen
  • int islower(int c) testet auf Kleinbuchstaben (a-z)
  • int isprint(int c) testet auf druckbare Zeichen mit Leerzeichen
  • int ispunct(int c) testet auf druckbare Interpunktionszeichen
  • int 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 um
  • int toupper(int c) wandelt Klein- in Grossbuchstaben um

Häufig gemachte Fehler

[Bearbeiten]

Wie 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))