Suche…


Klassifizieren von Zeichen, die aus einem Stream gelesen wurden

#include <ctype.h>
#include <stdio.h>

typedef struct {
  size_t space;
  size_t alnum;
  size_t punct;
} chartypes;

chartypes classify(FILE *f) {
  chartypes types = { 0, 0, 0 };
  int ch;

  while ((ch = fgetc(f)) != EOF) {
    types.space += !!isspace(ch);
    types.alnum += !!isalnum(ch);
    types.punct += !!ispunct(ch);
  }

  return types;
}

Die classify liest Zeichen aus einem Stream und zählt die Anzahl der Leerzeichen, alphanumerischen Zeichen und Satzzeichen. Es vermeidet mehrere Fallstricke.

  • Beim Lesen eines Zeichens aus einem Stream wird das Ergebnis als int gespeichert, da andernfalls das Lesen von EOF (Dateiendemarker) und ein Zeichen, das dasselbe Bitmuster aufweist, nicht eindeutig sind.
  • Die Zeichenklassifizierungsfunktionen (z. B. isspace ) erwarten, dass ihr Argument entweder als unsigned char Zeichen oder als Wert des EOF Makros darstellbar ist . Da dies genau das ist, was die fgetc zurückgibt, ist hier keine Konvertierung erforderlich.
  • Der Rückgabewert der Zeichenklassifizierungsfunktionen unterscheidet nur zwischen Null (Bedeutung false ) und Nicht-Null (Bedeutung true ). Um die Anzahl der Vorkommen zu zählen, muss dieser Wert in eine 1 oder 0 umgewandelt werden. Dies geschieht durch die doppelte Negation. !! .

Zeichen aus einer Zeichenfolge klassifizieren

#include <ctype.h>
#include <stddef.h>

typedef struct {
  size_t space;
  size_t alnum;
  size_t punct;
} chartypes;

chartypes classify(const char *s) {
  chartypes types = { 0, 0, 0 };
  const char *p;
  for (p= s; p != '\0'; p++) {
    types.space += !!isspace((unsigned char)*p);
    types.alnum += !!isalnum((unsigned char)*p);
    types.punct += !!ispunct((unsigned char)*p);
  }

  return types;
}

Die classify überprüft alle Zeichen einer Zeichenfolge und zählt die Anzahl der Leerzeichen, alphanumerischen Zeichen und Satzzeichen. Es vermeidet mehrere Fallstricke.

  • Die Zeichenklassifizierungsfunktionen (z. B. isspace ) erwarten, dass ihr Argument entweder als unsigned char Zeichen oder als Wert des EOF Makros darstellbar ist .
  • Der Ausdruck *p ist vom Typ char und muss daher entsprechend dem obigen Wortlaut konvertiert werden.
  • Der char Typ ist definiert als entweder signed char oder unsigned char .
  • Wenn char einem unsigned char , besteht kein Problem, da jeder mögliche Wert des Typs " char als unsigned char .
  • Wenn char äquivalent zu signed char , muss es in unsigned char umgewandelt werden, bevor es an die Zeichenklassifizierungsfunktionen übergeben wird. Und obwohl sich der Wert des Zeichens aufgrund dieser Konvertierung ändern kann, erwarten genau diese Funktionen diese Funktion.
  • Der Rückgabewert der Zeichenklassifizierungsfunktionen unterscheidet nur zwischen Null (Bedeutung false ) und Nicht-Null (Bedeutung true ). Um die Anzahl der Vorkommen zu zählen, muss dieser Wert in eine 1 oder 0 umgewandelt werden. Dies geschieht durch die doppelte Negation. !! .

Einführung

Der Header ctype.h ist Teil der Standard-C-Bibliothek. Es bietet Funktionen zum Klassifizieren und Konvertieren von Zeichen.

Alle diese Funktionen benötigen einen Parameter, ein int , das entweder EOF sein muss oder als vorzeichenloses Zeichen dargestellt werden kann.

Die Namen der klassifizierenden Funktionen sind mit 'is' versehen. Jeder gibt einen ganzzahligen Wert ungleich Null (TRUE) zurück, wenn das übergebene Zeichen die zugehörige Bedingung erfüllt. Wenn die Bedingung nicht erfüllt ist, gibt die Funktion einen Nullwert zurück (FALSE).

Diese Klassifizierungsfunktionen funktionieren wie gezeigt, vorausgesetzt, das Standardgebietsschema C wird verwendet:

int a;
int c = 'A';
a = isalpha(c); /* Checks if c is alphabetic (A-Z, a-z), returns non-zero here. */
a = isalnum(c); /* Checks if c  is alphanumeric (A-Z, a-z, 0-9), returns non-zero here. */
a = iscntrl(c); /* Checks is c is a control character (0x00-0x1F, 0x7F), returns zero here. */
a = isdigit(c); /* Checks if c is a digit (0-9), returns zero here. */
a = isgraph(c); /* Checks if c has a graphical representation (any printing character except space), returns non-zero here. */
a = islower(c); /* Checks if c is a lower-case letter (a-z), returns zero here. */
a = isprint(c); /* Checks if c is any printable character (including space), returns non-zero here. */
a = isupper(c); /* Checks if c is a upper-case letter (a-z), returns zero here. */
a = ispunct(c); /* Checks if c is a punctuation character, returns zero here. */
a = isspace(c); /* Checks if c is a white-space character, returns zero here. */
a = isupper(c); /* Checks if c is an upper-case letter (A-Z), returns non-zero here. */
a = isxdigit(c); /* Checks if c is a hexadecimal digit (A-F, a-f, 0-9), returns non-zero here. */
C99
a = isblank(c); /* Checks if c is a blank character (space or tab), returns non-zero here. */

Es gibt zwei Konvertierungsfunktionen. Diese werden mit dem Präfix 'bis' benannt. Für diese Funktionen gelten dieselben Argumente wie oben. Der Rückgabewert ist jedoch keine einfache Null oder Nicht-Null, sondern das übergebene Argument hat sich in gewisser Weise geändert.

Diese Konvertierungsfunktionen funktionieren wie gezeigt, vorausgesetzt, das Standardgebietsschema C wird verwendet:

int a;
int c = 'A';

/* Converts c to a lower-case letter (a-z). 
 * If conversion is not possible the unchanged value is returned. 
 * Returns 'a' here. 
 */
a = tolower(c);

/* Converts c to an upper-case letter (A-Z). 
 * If conversion is not possible the unchanged value is returned. 
 * Returns 'A' here. 
 */
a = toupper(c);

Die folgende Information wird aus cplusplus.com-Zitate zitiert, wie der ursprüngliche aus 127 Zeichen bestehende ASCII-Satz von jeder der klassifizierenden Typfunktionen betrachtet wird (a • zeigt an, dass die Funktion für dieses Zeichen nicht Null zurückgibt)

ASCII-Werte Zeichen iscntrl ist leer isspace Isupper ist tiefer isalpha isdigit isxdigit isalnum ispunct isgraph isprint
0x00 .. 0x08 NUL, (andere Steuercodes)
0x09 Tab ('\ t')
0x0A .. 0x0D (Leerraumkontrollcodes: '\ f', '\ v', '\ n', '\ r')
0x0E .. 0x1F (andere Steuercodes)
0x20 Platz (' ')
0x21 .. 0x2F ! "# $% & '() * +, -. /
0x30 .. 0x39 0123456789
0x3a .. 0x40 :; <=>? @
0x41 .. 0x46 ABCDEF
0x47 .. 0x5A GHIJKLMNOPQRSTUVWXYZ
0x5B .. 0x60 [] ^ _ `
0x61 .. 0x66 abcdef
0x67 .. 0x7A ghijklmnopqrstuvwxyz
0x7B .. 0x7E {} ~ bar
0x7F (DEL)


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow